@twinfinity/printing 6.0.1-ci.28952-beta → 6.0.2-beta
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.
- package/README.md +3 -3
- package/dist/BuildInfo.js +3 -3
- package/dist/BuildInfo.js.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/layout/analyzeTemplate.js.map +1 -1
- package/dist/layout/clipUtils.js.map +1 -1
- package/dist/layout/colorConstants.js.map +1 -1
- package/dist/layout/elementKinds.js.map +1 -1
- package/dist/layout/exportDrawing.js.map +1 -1
- package/dist/layout/filters.js.map +1 -1
- package/dist/layout/geometryConstants.js.map +1 -1
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/itemBuilders.js.map +1 -1
- package/dist/layout/labelsRender.js.map +1 -1
- package/dist/layout/legendConstants.js.map +1 -1
- package/dist/layout/legendRender.js.map +1 -1
- package/dist/layout/legendRows.js.map +1 -1
- package/dist/layout/legendUtils.js.map +1 -1
- package/dist/layout/metadata.js.map +1 -1
- package/dist/layout/model.js.map +1 -1
- package/dist/layout/options.js.map +1 -1
- package/dist/layout/presets.js.map +1 -1
- package/dist/layout/qrRender.js.map +1 -1
- package/dist/layout/renderDrawing.js.map +1 -1
- package/dist/layout/renderUtils.js.map +1 -1
- package/dist/layout/sectionValidation.js.map +1 -1
- package/dist/layout/templateVariables.js.map +1 -1
- package/dist/layout/typeGuards.js.map +1 -1
- package/dist/layout/types.js.map +1 -1
- package/dist/layout/utils.js.map +1 -1
- package/dist/layout/validation.js.map +1 -1
- package/dist/layout/validationHelpers.js.map +1 -1
- package/dist/layout/validationUtils.js.map +1 -1
- package/dist/layout/viewportPrep.js.map +1 -1
- package/dist/layout/viewportRender.js.map +1 -1
- package/dist/layout/viewportUtils.js.map +1 -1
- package/dist/layout/warnings.js.map +1 -1
- package/dist/printToPdf.js.map +1 -1
- package/dist/printToSvg.js.map +1 -1
- package/dist/sections.js.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +2 -2
- package/src/BuildInfo.ts +41 -41
- package/src/index.ts +10 -10
- package/src/layout/analyzeTemplate.ts +218 -218
- package/src/layout/clipUtils.ts +193 -193
- package/src/layout/colorConstants.ts +16 -16
- package/src/layout/elementKinds.ts +35 -35
- package/src/layout/exportDrawing.ts +206 -206
- package/src/layout/filters.ts +80 -80
- package/src/layout/geometryConstants.ts +11 -11
- package/src/layout/index.ts +671 -671
- package/src/layout/itemBuilders.ts +159 -159
- package/src/layout/labelsRender.ts +170 -170
- package/src/layout/legendConstants.ts +11 -11
- package/src/layout/legendRender.ts +543 -543
- package/src/layout/legendRows.ts +62 -62
- package/src/layout/legendUtils.ts +144 -144
- package/src/layout/metadata.ts +210 -210
- package/src/layout/model.ts +372 -372
- package/src/layout/options.ts +17 -17
- package/src/layout/presets.ts +51 -51
- package/src/layout/qrRender.ts +126 -126
- package/src/layout/qrcode.d.ts +2 -2
- package/src/layout/renderDrawing.ts +710 -710
- package/src/layout/renderUtils.ts +138 -138
- package/src/layout/sectionValidation.ts +2 -2
- package/src/layout/templateVariables.ts +317 -317
- package/src/layout/typeGuards.ts +9 -9
- package/src/layout/types.ts +835 -835
- package/src/layout/utils.ts +85 -85
- package/src/layout/validation.ts +392 -392
- package/src/layout/validationHelpers.ts +59 -59
- package/src/layout/validationUtils.ts +6 -6
- package/src/layout/viewportPrep.ts +351 -351
- package/src/layout/viewportRender.ts +442 -442
- package/src/layout/viewportUtils.ts +50 -50
- package/src/layout/warnings.ts +3 -3
- package/src/printToPdf.ts +108 -108
- package/src/printToSvg.ts +188 -188
- package/src/sections.ts +1019 -1019
- package/src/types.ts +49 -49
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewportPrep.js","sourceRoot":"/","sources":["layout/viewportPrep.ts"],"names":[],"mappings":"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","sourcesContent":["import { filterModelForViewport } from './model';\r\nimport { ModelMetadata } from './metadata';\r\nimport { ViewportElement, SvgModelView, ComputedViewportScale } from './types';\r\nimport { pushWarning } from './warnings';\r\nimport { pickScale } from './viewportUtils';\r\nimport type { ResolvedPresets } from './presets';\r\nimport { getPathValue } from './renderUtils';\r\nimport { pointInPolygon, offsetPolygons, Polygon } from './clipUtils';\r\nimport { matchesV2Filter, normalizeClass } from './filters';\r\nimport { EPSILON_MIN_DIMENSION } from './geometryConstants';\r\n\r\nexport interface ViewportPrepResult {\r\n viewportScales: Record<string, ComputedViewportScale>;\r\n viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>>;\r\n viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>>;\r\n viewportClipBounds: Record<\r\n string,\r\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\r\n >;\r\n viewportClipLabels: Record<string, boolean>;\r\n viewportClipStyles: Record<\r\n string,\r\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\r\n >;\r\n viewportClipWhere: Record<string, WhereCondition | undefined>;\r\n viewportHighlight: Record<\r\n string,\r\n {\r\n gids: Set<string> | null;\r\n styles: {\r\n stroke?: string;\r\n strokeWidthMm?: number;\r\n strokeOpacity?: number;\r\n fill?: string;\r\n fillOpacity?: number;\r\n };\r\n }\r\n >;\r\n filteredModelsByViewport: Record<string, SvgModelView>;\r\n}\r\n\r\nimport { isRecord, getProp } from './typeGuards';\r\nimport type { WhereCondition } from './types';\r\n\r\nexport const prepareViewports = (\r\n viewports: ViewportElement[],\r\n models: Record<string, SvgModelView | undefined>,\r\n data: unknown,\r\n preferredScales: number[],\r\n presets: ResolvedPresets,\r\n options: { metadataById?: unknown; warnings: string[] }\r\n): ViewportPrepResult => {\r\n const viewportScales: Record<string, ComputedViewportScale> = {};\r\n const viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>> = {};\r\n const viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>> = {};\r\n const viewportClipBounds: Record<\r\n string,\r\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\r\n > = {};\r\n const viewportClipLabels: Record<string, boolean> = {};\r\n const viewportClipStyles: Record<\r\n string,\r\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\r\n > = {};\r\n const viewportClipWhere: Record<string, WhereCondition | undefined> = {};\r\n const viewportHighlight: ViewportPrepResult['viewportHighlight'] = {};\r\n const filteredModelsByViewport: Record<string, SvgModelView> = {};\r\n const scales = presets.scales;\r\n\r\n viewports.forEach((vp) => {\r\n const baseModel = models[vp.id];\r\n let clipAllowedGids: Set<string> | null = null;\r\n\r\n // Highlight: optional class+where filter on normalized items\r\n let highlightGids: Set<string> | null = null;\r\n const hlCfg = vp.highlight;\r\n if (hlCfg && hlCfg.where) {\r\n const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);\r\n if (Array.isArray(sourceItems) && sourceItems.length) {\r\n const matching = sourceItems.filter((it) => matchesV2Filter(it, hlCfg.class, hlCfg.where));\r\n if (matching.length) {\r\n highlightGids = new Set(\r\n matching\r\n .map((it: unknown) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)\r\n .filter((v: unknown) => v !== null && v !== undefined)\r\n .map((v: unknown) => String(v))\r\n );\r\n\r\n // Intersect with referenced viewport if specified\r\n if (hlCfg.intersectsViewport) {\r\n const refItems = getPathValue(data, `viewports.${hlCfg.intersectsViewport}.items`);\r\n if (Array.isArray(refItems) && refItems.length) {\r\n const refGids = new Set(\r\n refItems\r\n .map((it: unknown) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)\r\n .filter((v: unknown) => v !== null && v !== undefined)\r\n .map((v: unknown) => String(v))\r\n );\r\n // Keep only items that appear in both viewports\r\n const intersection = new Set<string>();\r\n highlightGids.forEach((gid) => {\r\n if (refGids.has(gid)) intersection.add(gid);\r\n });\r\n highlightGids = intersection;\r\n } else {\r\n pushWarning(\r\n options.warnings,\r\n `Viewport '${vp.id}' highlight intersectsViewport=\"${hlCfg.intersectsViewport}\": referenced viewport has no items.`\r\n );\r\n highlightGids = new Set(); // No items in referenced viewport = no highlights\r\n }\r\n }\r\n } else {\r\n highlightGids = new Set(); // explicit no matches\r\n pushWarning(\r\n options.warnings,\r\n `Viewport '${vp.id}' highlight filter matched 0 of ${sourceItems.length} items.`\r\n );\r\n }\r\n } else if (Array.isArray(sourceItems) && !sourceItems.length) {\r\n pushWarning(options.warnings, `Viewport '${vp.id}' highlight: no items available to filter.`);\r\n }\r\n }\r\n\r\n // Clip: class+where filter — find matching items, extract their polylines as clip polygons\r\n let clipEffectiveWidthModel: number | undefined;\r\n let clipEffectiveHeightModel: number | undefined;\r\n const clipCfg = vp.clip;\r\n if (clipCfg && clipCfg.where && baseModel?.transform) {\r\n viewportClipWhere[vp.id] = clipCfg.where;\r\n const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);\r\n if (Array.isArray(sourceItems) && sourceItems.length) {\r\n const matchingItems = sourceItems.filter((it) => matchesV2Filter(it, clipCfg.class, clipCfg.where));\r\n if (!matchingItems.length) {\r\n pushWarning(\r\n options.warnings,\r\n `Viewport '${vp.id}' clip filter matched 0 of ${sourceItems.length} items.`\r\n );\r\n }\r\n\r\n // Extract polylines from matched items\r\n const allPolylines: Array<{ points?: Array<{ x: number; z: number }> }> = [];\r\n for (const item of matchingItems) {\r\n const polylines = getProp(item, 'polylines');\r\n if (Array.isArray(polylines)) {\r\n for (const pl of polylines) {\r\n if (isRecord(pl)) allPolylines.push(pl as { points?: Array<{ x: number; z: number }> });\r\n }\r\n }\r\n }\r\n\r\n if (allPolylines.length) {\r\n // Project polyline points from world (x/z) to model view space\r\n const projectedLocal: Polygon[] = [];\r\n for (const poly of allPolylines) {\r\n const pts = poly.points;\r\n if (!Array.isArray(pts) || pts.length < 3) continue;\r\n const mapped: Polygon = [];\r\n for (const pt of pts) {\r\n const px = pt?.x;\r\n const pz = pt?.z;\r\n if (!Number.isFinite(px) || !Number.isFinite(pz)) continue;\r\n mapped.push({\r\n x: px - baseModel.transform!.viewMinX,\r\n y: baseModel.transform!.viewMaxZ - pz\r\n });\r\n }\r\n if (mapped.length >= 3) projectedLocal.push(mapped);\r\n }\r\n const expandByM =\r\n typeof clipCfg.expandByM === 'number' &&\r\n Number.isFinite(clipCfg.expandByM) &&\r\n clipCfg.expandByM > 0\r\n ? clipCfg.expandByM\r\n : 0;\r\n const buffered = expandByM > 0 ? offsetPolygons(projectedLocal, expandByM) : projectedLocal;\r\n\r\n if (buffered.length) {\r\n // Calculate bounds from EXPANDED polygon for viewport sizing (so everything fits)\r\n // Fill filtering (clipAllowedGids) uses ORIGINAL polygon from worldPolygons (line 239)\r\n const boundsSource = buffered; // Use EXPANDED for viewport sizing\r\n const flat = boundsSource.flat();\r\n let minX = Infinity,\r\n maxX = -Infinity,\r\n minY = Infinity,\r\n maxY = -Infinity;\r\n for (let i = 0; i < flat.length; i++) {\r\n const p = flat[i];\r\n if (p.x < minX) minX = p.x;\r\n if (p.x > maxX) maxX = p.x;\r\n if (p.y < minY) minY = p.y;\r\n if (p.y > maxY) maxY = p.y;\r\n }\r\n clipEffectiveWidthModel = Math.max(EPSILON_MIN_DIMENSION, maxX - minX);\r\n clipEffectiveHeightModel = Math.max(EPSILON_MIN_DIMENSION, maxY - minY);\r\n viewportClipPolygonsLocal[vp.id] = buffered;\r\n viewportClipLabels[vp.id] = !!clipCfg.clipLabels;\r\n viewportClipStyles[vp.id] = {\r\n stroke: clipCfg.stroke ?? '#000000',\r\n strokeWidthMm: clipCfg.strokeWidthMm ?? 0.5,\r\n strokeOpacity: clipCfg.strokeOpacity ?? 1,\r\n fill: clipCfg.fill ?? 'none',\r\n fillOpacity: clipCfg.fillOpacity ?? 0\r\n };\r\n viewportClipBounds[vp.id] = {\r\n minX,\r\n maxX,\r\n minY,\r\n maxY,\r\n width: clipEffectiveWidthModel,\r\n height: clipEffectiveHeightModel\r\n };\r\n\r\n // Build clipAllowedGids: include items whose center falls inside the clip polygons\r\n // Polygon is in XZ coordinates (horizontal plane), Y is vertical (plane height)\r\n const worldPolygons = allPolylines\r\n .filter((pl) => Array.isArray(pl.points) && pl.points.length >= 3)\r\n .map((pl) => pl.points!.map((p) => ({ x: p.x, z: p.z })));\r\n if (worldPolygons.length) {\r\n viewportClipPolygonsWorld[vp.id] = worldPolygons;\r\n clipAllowedGids = new Set<string>();\r\n for (const item of sourceItems) {\r\n // Use item's direct x/z properties (same approach as labels)\r\n const ix = getProp(item, 'x');\r\n const iz = getProp(item, 'z');\r\n\r\n if (!Number.isFinite(ix) || !Number.isFinite(iz)) {\r\n continue;\r\n }\r\n // Convert polygon {x,z} to {x,y} for pointInPolygon (same as labels do)\r\n const inside = worldPolygons.some((poly) => {\r\n const polyWith2D = poly.map((p) => ({ x: p.x, y: p.z }));\r\n return pointInPolygon(polyWith2D, ix as number, iz as number);\r\n });\r\n if (inside) {\r\n const gid = getProp(item, 'gid') ?? getProp(item, 'id');\r\n if (gid !== null && gid !== undefined) {\r\n clipAllowedGids.add(String(gid));\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Effective allowed set: if highlight defined, use highlight set; else clipAllowed; if both exist, intersect.\r\n // IMPORTANT: Store empty Set (not null) when clip filtering is active but finds no matches\r\n let effectiveAllowed: Set<string> | null = null;\r\n if (highlightGids && highlightGids.size > 0 && clipAllowedGids) {\r\n // Both highlight and clip active - intersect them (even if clipAllowedGids is empty)\r\n const intersection = new Set<string>();\r\n highlightGids.forEach((gid) => {\r\n if (clipAllowedGids!.has(gid)) intersection.add(gid);\r\n });\r\n effectiveAllowed = intersection;\r\n } else if (highlightGids && highlightGids.size > 0) {\r\n effectiveAllowed = highlightGids;\r\n } else if (clipAllowedGids !== null) {\r\n // Clip filtering is active - use clipAllowedGids even if empty (means zero items allowed)\r\n effectiveAllowed = clipAllowedGids;\r\n }\r\n\r\n const hlStyles = hlCfg\r\n ? {\r\n stroke: typeof hlCfg.stroke === 'string' ? hlCfg.stroke : '#ff0000',\r\n strokeWidthMm: typeof hlCfg.strokeWidthMm === 'number' ? hlCfg.strokeWidthMm : 0.5,\r\n strokeOpacity: typeof hlCfg.strokeOpacity === 'number' ? hlCfg.strokeOpacity : 1,\r\n fill: typeof hlCfg.fill === 'string' ? hlCfg.fill : '#ffff00',\r\n fillOpacity: typeof hlCfg.fillOpacity === 'number' ? hlCfg.fillOpacity : 0.5\r\n }\r\n : {\r\n stroke: undefined,\r\n strokeWidthMm: undefined,\r\n strokeOpacity: undefined,\r\n fill: undefined,\r\n fillOpacity: undefined\r\n };\r\n\r\n // Build the set of classes subject to GID-based filtering from highlight/clip configs\r\n const filterClasses = new Set<string>();\r\n const addFilterClasses = (cls: string | string[] | undefined): void => {\r\n if (!cls) return;\r\n const classes = Array.isArray(cls) ? cls : [cls];\r\n for (const c of classes) {\r\n const normalized = normalizeClass(c);\r\n if (normalized) filterClasses.add(normalized);\r\n }\r\n };\r\n addFilterClasses(hlCfg?.class);\r\n addFilterClasses(clipCfg?.class);\r\n\r\n const model = baseModel\r\n ? filterModelForViewport(\r\n baseModel,\r\n vp,\r\n options?.metadataById as ModelMetadata | undefined,\r\n presets.includeClasses,\r\n effectiveAllowed,\r\n {\r\n gids: highlightGids,\r\n styles: hlStyles\r\n },\r\n filterClasses.size > 0 ? filterClasses : null\r\n )\r\n : null;\r\n viewportHighlight[vp.id] = {\r\n gids: effectiveAllowed, // Use effectiveAllowed (includes both clip and highlight GIDs)\r\n styles: hlStyles\r\n };\r\n if (!model) {\r\n pushWarning(options.warnings, `Missing model for viewport '${vp.id}'.`);\r\n return;\r\n }\r\n filteredModelsByViewport[vp.id] = model;\r\n const effectiveWidthModel = clipEffectiveWidthModel ?? model.widthModel;\r\n const effectiveHeightModel = clipEffectiveHeightModel ?? model.heightModel;\r\n\r\n const scale = pickScale(\r\n vp,\r\n { ...model, widthModel: effectiveWidthModel, heightModel: effectiveHeightModel },\r\n preferredScales,\r\n scales\r\n );\r\n viewportScales[vp.id] = scale;\r\n viewportClipBounds[vp.id] = viewportClipBounds[vp.id] ?? {\r\n minX: model.transform?.viewMinX ?? 0,\r\n maxX: model.transform ? model.transform.viewMinX + effectiveWidthModel : effectiveWidthModel,\r\n minY: model.transform?.viewMinZ ?? 0,\r\n maxY: model.transform ? model.transform.viewMinZ + effectiveHeightModel : effectiveHeightModel,\r\n width: effectiveWidthModel,\r\n height: effectiveHeightModel\r\n };\r\n if (!viewportClipPolygonsLocal[vp.id]) {\r\n viewportClipPolygonsLocal[vp.id] = [];\r\n }\r\n });\r\n\r\n return {\r\n viewportScales,\r\n viewportClipPolygonsLocal,\r\n viewportClipPolygonsWorld,\r\n viewportClipBounds,\r\n viewportClipLabels,\r\n viewportClipStyles,\r\n viewportClipWhere,\r\n viewportHighlight,\r\n filteredModelsByViewport\r\n };\r\n};\r\n"]}
|
|
1
|
+
{"version":3,"file":"viewportPrep.js","sourceRoot":"/","sources":["layout/viewportPrep.ts"],"names":[],"mappings":"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","sourcesContent":["import { filterModelForViewport } from './model';\nimport { ModelMetadata } from './metadata';\nimport { ViewportElement, SvgModelView, ComputedViewportScale } from './types';\nimport { pushWarning } from './warnings';\nimport { pickScale } from './viewportUtils';\nimport type { ResolvedPresets } from './presets';\nimport { getPathValue } from './renderUtils';\nimport { pointInPolygon, offsetPolygons, Polygon } from './clipUtils';\nimport { matchesV2Filter, normalizeClass } from './filters';\nimport { EPSILON_MIN_DIMENSION } from './geometryConstants';\n\nexport interface ViewportPrepResult {\n viewportScales: Record<string, ComputedViewportScale>;\n viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>>;\n viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>>;\n viewportClipBounds: Record<\n string,\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\n >;\n viewportClipLabels: Record<string, boolean>;\n viewportClipStyles: Record<\n string,\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\n >;\n viewportClipWhere: Record<string, WhereCondition | undefined>;\n viewportHighlight: Record<\n string,\n {\n gids: Set<string> | null;\n styles: {\n stroke?: string;\n strokeWidthMm?: number;\n strokeOpacity?: number;\n fill?: string;\n fillOpacity?: number;\n };\n }\n >;\n filteredModelsByViewport: Record<string, SvgModelView>;\n}\n\nimport { isRecord, getProp } from './typeGuards';\nimport type { WhereCondition } from './types';\n\nexport const prepareViewports = (\n viewports: ViewportElement[],\n models: Record<string, SvgModelView | undefined>,\n data: unknown,\n preferredScales: number[],\n presets: ResolvedPresets,\n options: { metadataById?: unknown; warnings: string[] }\n): ViewportPrepResult => {\n const viewportScales: Record<string, ComputedViewportScale> = {};\n const viewportClipPolygonsLocal: Record<string, Array<Array<{ x: number; y: number }>>> = {};\n const viewportClipPolygonsWorld: Record<string, Array<Array<{ x: number; z: number }>>> = {};\n const viewportClipBounds: Record<\n string,\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\n > = {};\n const viewportClipLabels: Record<string, boolean> = {};\n const viewportClipStyles: Record<\n string,\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\n > = {};\n const viewportClipWhere: Record<string, WhereCondition | undefined> = {};\n const viewportHighlight: ViewportPrepResult['viewportHighlight'] = {};\n const filteredModelsByViewport: Record<string, SvgModelView> = {};\n const scales = presets.scales;\n\n viewports.forEach((vp) => {\n const baseModel = models[vp.id];\n let clipAllowedGids: Set<string> | null = null;\n\n // Highlight: optional class+where filter on normalized items\n let highlightGids: Set<string> | null = null;\n const hlCfg = vp.highlight;\n if (hlCfg && hlCfg.where) {\n const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);\n if (Array.isArray(sourceItems) && sourceItems.length) {\n const matching = sourceItems.filter((it) => matchesV2Filter(it, hlCfg.class, hlCfg.where));\n if (matching.length) {\n highlightGids = new Set(\n matching\n .map((it: unknown) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)\n .filter((v: unknown) => v !== null && v !== undefined)\n .map((v: unknown) => String(v))\n );\n\n // Intersect with referenced viewport if specified\n if (hlCfg.intersectsViewport) {\n const refItems = getPathValue(data, `viewports.${hlCfg.intersectsViewport}.items`);\n if (Array.isArray(refItems) && refItems.length) {\n const refGids = new Set(\n refItems\n .map((it: unknown) => getProp(it, 'gid') ?? getProp(it, 'id') ?? null)\n .filter((v: unknown) => v !== null && v !== undefined)\n .map((v: unknown) => String(v))\n );\n // Keep only items that appear in both viewports\n const intersection = new Set<string>();\n highlightGids.forEach((gid) => {\n if (refGids.has(gid)) intersection.add(gid);\n });\n highlightGids = intersection;\n } else {\n pushWarning(\n options.warnings,\n `Viewport '${vp.id}' highlight intersectsViewport=\"${hlCfg.intersectsViewport}\": referenced viewport has no items.`\n );\n highlightGids = new Set(); // No items in referenced viewport = no highlights\n }\n }\n } else {\n highlightGids = new Set(); // explicit no matches\n pushWarning(\n options.warnings,\n `Viewport '${vp.id}' highlight filter matched 0 of ${sourceItems.length} items.`\n );\n }\n } else if (Array.isArray(sourceItems) && !sourceItems.length) {\n pushWarning(options.warnings, `Viewport '${vp.id}' highlight: no items available to filter.`);\n }\n }\n\n // Clip: class+where filter — find matching items, extract their polylines as clip polygons\n let clipEffectiveWidthModel: number | undefined;\n let clipEffectiveHeightModel: number | undefined;\n const clipCfg = vp.clip;\n if (clipCfg && clipCfg.where && baseModel?.transform) {\n viewportClipWhere[vp.id] = clipCfg.where;\n const sourceItems = getPathValue(data, `viewports.${vp.id}.items`);\n if (Array.isArray(sourceItems) && sourceItems.length) {\n const matchingItems = sourceItems.filter((it) => matchesV2Filter(it, clipCfg.class, clipCfg.where));\n if (!matchingItems.length) {\n pushWarning(\n options.warnings,\n `Viewport '${vp.id}' clip filter matched 0 of ${sourceItems.length} items.`\n );\n }\n\n // Extract polylines from matched items\n const allPolylines: Array<{ points?: Array<{ x: number; z: number }> }> = [];\n for (const item of matchingItems) {\n const polylines = getProp(item, 'polylines');\n if (Array.isArray(polylines)) {\n for (const pl of polylines) {\n if (isRecord(pl)) allPolylines.push(pl as { points?: Array<{ x: number; z: number }> });\n }\n }\n }\n\n if (allPolylines.length) {\n // Project polyline points from world (x/z) to model view space\n const projectedLocal: Polygon[] = [];\n for (const poly of allPolylines) {\n const pts = poly.points;\n if (!Array.isArray(pts) || pts.length < 3) continue;\n const mapped: Polygon = [];\n for (const pt of pts) {\n const px = pt?.x;\n const pz = pt?.z;\n if (!Number.isFinite(px) || !Number.isFinite(pz)) continue;\n mapped.push({\n x: px - baseModel.transform!.viewMinX,\n y: baseModel.transform!.viewMaxZ - pz\n });\n }\n if (mapped.length >= 3) projectedLocal.push(mapped);\n }\n const expandByM =\n typeof clipCfg.expandByM === 'number' &&\n Number.isFinite(clipCfg.expandByM) &&\n clipCfg.expandByM > 0\n ? clipCfg.expandByM\n : 0;\n const buffered = expandByM > 0 ? offsetPolygons(projectedLocal, expandByM) : projectedLocal;\n\n if (buffered.length) {\n // Calculate bounds from EXPANDED polygon for viewport sizing (so everything fits)\n // Fill filtering (clipAllowedGids) uses ORIGINAL polygon from worldPolygons (line 239)\n const boundsSource = buffered; // Use EXPANDED for viewport sizing\n const flat = boundsSource.flat();\n let minX = Infinity,\n maxX = -Infinity,\n minY = Infinity,\n maxY = -Infinity;\n for (let i = 0; i < flat.length; i++) {\n const p = flat[i];\n if (p.x < minX) minX = p.x;\n if (p.x > maxX) maxX = p.x;\n if (p.y < minY) minY = p.y;\n if (p.y > maxY) maxY = p.y;\n }\n clipEffectiveWidthModel = Math.max(EPSILON_MIN_DIMENSION, maxX - minX);\n clipEffectiveHeightModel = Math.max(EPSILON_MIN_DIMENSION, maxY - minY);\n viewportClipPolygonsLocal[vp.id] = buffered;\n viewportClipLabels[vp.id] = !!clipCfg.clipLabels;\n viewportClipStyles[vp.id] = {\n stroke: clipCfg.stroke ?? '#000000',\n strokeWidthMm: clipCfg.strokeWidthMm ?? 0.5,\n strokeOpacity: clipCfg.strokeOpacity ?? 1,\n fill: clipCfg.fill ?? 'none',\n fillOpacity: clipCfg.fillOpacity ?? 0\n };\n viewportClipBounds[vp.id] = {\n minX,\n maxX,\n minY,\n maxY,\n width: clipEffectiveWidthModel,\n height: clipEffectiveHeightModel\n };\n\n // Build clipAllowedGids: include items whose center falls inside the clip polygons\n // Polygon is in XZ coordinates (horizontal plane), Y is vertical (plane height)\n const worldPolygons = allPolylines\n .filter((pl) => Array.isArray(pl.points) && pl.points.length >= 3)\n .map((pl) => pl.points!.map((p) => ({ x: p.x, z: p.z })));\n if (worldPolygons.length) {\n viewportClipPolygonsWorld[vp.id] = worldPolygons;\n clipAllowedGids = new Set<string>();\n for (const item of sourceItems) {\n // Use item's direct x/z properties (same approach as labels)\n const ix = getProp(item, 'x');\n const iz = getProp(item, 'z');\n\n if (!Number.isFinite(ix) || !Number.isFinite(iz)) {\n continue;\n }\n // Convert polygon {x,z} to {x,y} for pointInPolygon (same as labels do)\n const inside = worldPolygons.some((poly) => {\n const polyWith2D = poly.map((p) => ({ x: p.x, y: p.z }));\n return pointInPolygon(polyWith2D, ix as number, iz as number);\n });\n if (inside) {\n const gid = getProp(item, 'gid') ?? getProp(item, 'id');\n if (gid !== null && gid !== undefined) {\n clipAllowedGids.add(String(gid));\n }\n }\n }\n }\n }\n }\n }\n }\n\n // Effective allowed set: if highlight defined, use highlight set; else clipAllowed; if both exist, intersect.\n // IMPORTANT: Store empty Set (not null) when clip filtering is active but finds no matches\n let effectiveAllowed: Set<string> | null = null;\n if (highlightGids && highlightGids.size > 0 && clipAllowedGids) {\n // Both highlight and clip active - intersect them (even if clipAllowedGids is empty)\n const intersection = new Set<string>();\n highlightGids.forEach((gid) => {\n if (clipAllowedGids!.has(gid)) intersection.add(gid);\n });\n effectiveAllowed = intersection;\n } else if (highlightGids && highlightGids.size > 0) {\n effectiveAllowed = highlightGids;\n } else if (clipAllowedGids !== null) {\n // Clip filtering is active - use clipAllowedGids even if empty (means zero items allowed)\n effectiveAllowed = clipAllowedGids;\n }\n\n const hlStyles = hlCfg\n ? {\n stroke: typeof hlCfg.stroke === 'string' ? hlCfg.stroke : '#ff0000',\n strokeWidthMm: typeof hlCfg.strokeWidthMm === 'number' ? hlCfg.strokeWidthMm : 0.5,\n strokeOpacity: typeof hlCfg.strokeOpacity === 'number' ? hlCfg.strokeOpacity : 1,\n fill: typeof hlCfg.fill === 'string' ? hlCfg.fill : '#ffff00',\n fillOpacity: typeof hlCfg.fillOpacity === 'number' ? hlCfg.fillOpacity : 0.5\n }\n : {\n stroke: undefined,\n strokeWidthMm: undefined,\n strokeOpacity: undefined,\n fill: undefined,\n fillOpacity: undefined\n };\n\n // Build the set of classes subject to GID-based filtering from highlight/clip configs\n const filterClasses = new Set<string>();\n const addFilterClasses = (cls: string | string[] | undefined): void => {\n if (!cls) return;\n const classes = Array.isArray(cls) ? cls : [cls];\n for (const c of classes) {\n const normalized = normalizeClass(c);\n if (normalized) filterClasses.add(normalized);\n }\n };\n addFilterClasses(hlCfg?.class);\n addFilterClasses(clipCfg?.class);\n\n const model = baseModel\n ? filterModelForViewport(\n baseModel,\n vp,\n options?.metadataById as ModelMetadata | undefined,\n presets.includeClasses,\n effectiveAllowed,\n {\n gids: highlightGids,\n styles: hlStyles\n },\n filterClasses.size > 0 ? filterClasses : null\n )\n : null;\n viewportHighlight[vp.id] = {\n gids: effectiveAllowed, // Use effectiveAllowed (includes both clip and highlight GIDs)\n styles: hlStyles\n };\n if (!model) {\n pushWarning(options.warnings, `Missing model for viewport '${vp.id}'.`);\n return;\n }\n filteredModelsByViewport[vp.id] = model;\n const effectiveWidthModel = clipEffectiveWidthModel ?? model.widthModel;\n const effectiveHeightModel = clipEffectiveHeightModel ?? model.heightModel;\n\n const scale = pickScale(\n vp,\n { ...model, widthModel: effectiveWidthModel, heightModel: effectiveHeightModel },\n preferredScales,\n scales\n );\n viewportScales[vp.id] = scale;\n viewportClipBounds[vp.id] = viewportClipBounds[vp.id] ?? {\n minX: model.transform?.viewMinX ?? 0,\n maxX: model.transform ? model.transform.viewMinX + effectiveWidthModel : effectiveWidthModel,\n minY: model.transform?.viewMinZ ?? 0,\n maxY: model.transform ? model.transform.viewMinZ + effectiveHeightModel : effectiveHeightModel,\n width: effectiveWidthModel,\n height: effectiveHeightModel\n };\n if (!viewportClipPolygonsLocal[vp.id]) {\n viewportClipPolygonsLocal[vp.id] = [];\n }\n });\n\n return {\n viewportScales,\n viewportClipPolygonsLocal,\n viewportClipPolygonsWorld,\n viewportClipBounds,\n viewportClipLabels,\n viewportClipStyles,\n viewportClipWhere,\n viewportHighlight,\n filteredModelsByViewport\n };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewportRender.js","sourceRoot":"/","sources":["layout/viewportRender.ts"],"names":[],"mappings":"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","sourcesContent":["import { escapeAttr, getPathValue, resolvePath } from './renderUtils';\r\nimport { rotateBounds, pickScale } from './viewportUtils';\r\nimport { ViewportRenderInfo } from './labelsRender';\r\nimport { matchesV2Filter } from './filters';\r\nimport { ComputedViewportScale, SvgModelView, ViewportElement, AssetSpec } from './types';\r\nimport { isRecord, getProp } from './typeGuards';\r\n\r\ntype PolyPoint = { x: number; y: number };\r\n// Debug overlay for clip polygons. Keep false for normal builds.\r\nconst DEBUG_CLIP_OVERLAY = false;\r\n\r\ntype Mat = [number, number, number, number, number, number]; // a b c d e f\r\n\r\nconst matTranslate = (tx: number, ty: number): Mat => [1, 0, 0, 1, tx, ty];\r\nconst matScale = (sx: number, sy: number): Mat => [sx, 0, 0, sy, 0, 0];\r\nconst matRotateDeg = (deg: number): Mat => {\r\n const rad = (deg * Math.PI) / 180;\r\n const c = Math.cos(rad);\r\n const s = Math.sin(rad);\r\n return [c, s, -s, c, 0, 0];\r\n};\r\nconst matMultiply = (m1: Mat, m2: Mat): Mat => {\r\n const [a1, b1, c1, d1, e1, f1] = m1;\r\n const [a2, b2, c2, d2, e2, f2] = m2;\r\n return [\r\n a1 * a2 + c1 * b2,\r\n b1 * a2 + d1 * b2,\r\n a1 * c2 + c1 * d2,\r\n b1 * c2 + d1 * d2,\r\n a1 * e2 + c1 * f2 + e1,\r\n b1 * e2 + d1 * f2 + f1\r\n ];\r\n};\r\nconst matApply = (m: Mat, p: PolyPoint): PolyPoint => {\r\n const [a, b, c, d, e, f] = m;\r\n return { x: a * p.x + c * p.y + e, y: b * p.x + d * p.y + f };\r\n};\r\nexport const renderViewportElement = (\r\n vp: ViewportElement,\r\n baseModel: SvgModelView | null,\r\n dataWithViewport: any,\r\n preferredScales: number[],\r\n scales: Record<string, { preferredScales?: number[] }>,\r\n assetMap: Map<string, AssetSpec>,\r\n viewportScales: Record<string, ComputedViewportScale>,\r\n viewportClipPolygonsLocal: Record<string, Array<Array<PolyPoint>>>,\r\n viewportClipBounds: Record<\r\n string,\r\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\r\n >,\r\n viewportClipLabels: Record<string, boolean>,\r\n viewportClipStyles: Record<\r\n string,\r\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\r\n >,\r\n viewportHighlight: Record<string, { gids: Set<string> | null; styles: any }>,\r\n viewportRenderInfo: Record<string, ViewportRenderInfo>,\r\n warnings: string[],\r\n legendColorMaps?: Map<string, Map<string, string>>,\r\n precomputed?: {\r\n effectiveWidthModel?: number;\r\n effectiveHeightModel?: number;\r\n clipPolygonsMm?: Array<Array<PolyPoint>>;\r\n clipPolygonsLocal?: Array<Array<PolyPoint>>;\r\n clipBounds?: { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number };\r\n renderCenterModelX?: number;\r\n renderCenterModelY?: number;\r\n }\r\n): string[] => {\r\n const parts: string[] = [];\r\n if (!baseModel) {\r\n // Warning already pushed by viewportPrep; avoid duplicate.\r\n return parts;\r\n }\r\n\r\n const model = baseModel;\r\n let renderWidthModel = precomputed?.effectiveWidthModel ?? model.widthModel;\r\n let renderHeightModel = precomputed?.effectiveHeightModel ?? model.heightModel;\r\n let renderCenterModelX = precomputed?.renderCenterModelX ?? renderWidthModel * 0.5;\r\n let renderCenterModelY = precomputed?.renderCenterModelY ?? renderHeightModel * 0.5;\r\n\r\n const clipBounds = viewportClipBounds[vp.id];\r\n const clipLocal = viewportClipPolygonsLocal[vp.id];\r\n const hasClip = !!clipBounds && Array.isArray(clipLocal) && clipLocal.length > 0;\r\n if (hasClip) {\r\n renderWidthModel = clipBounds!.width;\r\n renderHeightModel = clipBounds!.height;\r\n renderCenterModelX = (clipBounds!.minX + clipBounds!.maxX) * 0.5;\r\n renderCenterModelY = (clipBounds!.minY + clipBounds!.maxY) * 0.5;\r\n }\r\n\r\n const scaleInfo =\r\n viewportScales[vp.id] ??\r\n pickScale(\r\n vp,\r\n { ...model, widthModel: renderWidthModel, heightModel: renderHeightModel },\r\n preferredScales,\r\n scales\r\n );\r\n const rotationDeg = vp.rotationDeg ?? 0;\r\n const mmPerModel = scaleInfo.mmPerModelUnit;\r\n const contentWidthMm = renderWidthModel * mmPerModel;\r\n const contentHeightMm = renderHeightModel * mmPerModel;\r\n const rotated = rotateBounds(contentWidthMm, contentHeightMm, rotationDeg);\r\n\r\n const centerX = vp.align === 'topLeft' ? vp.xMm + rotated.width / 2 : vp.xMm + vp.widthMm / 2;\r\n const centerY = vp.align === 'topLeft' ? vp.yMm + rotated.height / 2 : vp.yMm + vp.heightMm / 2;\r\n\r\n const contentOffsetX = vp.align === 'topLeft' ? vp.xMm : vp.xMm + Math.max(0, (vp.widthMm - rotated.width) * 0.5);\r\n const contentOffsetY = vp.align === 'topLeft' ? vp.yMm : vp.yMm + Math.max(0, (vp.heightMm - rotated.height) * 0.5);\r\n\r\n const clipPolysLocal = clipLocal;\r\n let clipId: string | null = null;\r\n const clipDebugPolys: string[] = [];\r\n const clipStyle = viewportClipStyles[vp.id];\r\n const clipStroke = clipStyle?.stroke;\r\n const clipStrokeWidth = clipStyle?.strokeWidthMm;\r\n const clipStrokeOpacity = clipStyle?.strokeOpacity;\r\n const clipFill = clipStyle?.fill;\r\n const clipFillOpacity = clipStyle?.fillOpacity;\r\n const transformAttr = `translate(${centerX} ${centerY}) rotate(${rotationDeg}) scale(${mmPerModel}) translate(${-renderCenterModelX} ${-renderCenterModelY})`;\r\n\r\n // Debug: log model bounds and path breakdown\r\n // if (model.transform) {\r\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] Model bounds: viewMinX=${model.transform.viewMinX.toFixed(2)} viewMaxX=${model.transform.viewMaxX?.toFixed(2)} viewMinZ=${model.transform.viewMinZ.toFixed(2)} viewMaxZ=${model.transform.viewMaxZ.toFixed(2)} viewWidth=${model.transform.viewWidth.toFixed(2)} viewHeight=${model.transform.viewHeight.toFixed(2)}`);\r\n\r\n // if (model.rawPaths) {\r\n // const fills = model.rawPaths.filter(p => p.meta?.isFill);\r\n // const segments = model.rawPaths.filter(p => p.meta?.isSegment);\r\n // const other = model.rawPaths.filter(p => !p.meta?.isFill && !p.meta?.isSegment);\r\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] Path breakdown: ${model.rawPaths.length} total (${fills.length} fills, ${segments.length} segments, ${other.length} other)`);\r\n\r\n // // Sample a few segment paths\r\n // const sampleSegments = segments.slice(0, 3);\r\n // sampleSegments.forEach((seg, idx) => {\r\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] Segment ${idx}: class=${seg.meta?.class} fill=${seg.fill} stroke=${seg.stroke} strokeWidth=${seg.strokeWidth} d=${seg.d.substring(0, 50)}...`);\r\n // });\r\n\r\n // // Check if geometryTransform is present\r\n // if (model.geometryTransform) {\r\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] geometryTransform=\"${model.geometryTransform}\"`);\r\n // } else {\r\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] WARNING: geometryTransform is MISSING!`);\r\n // }\r\n // }\r\n // }\r\n\r\n // Guard: detect NaN/Infinity in computed transform values\r\n if (\r\n !Number.isFinite(centerX) ||\r\n !Number.isFinite(centerY) ||\r\n !Number.isFinite(mmPerModel) ||\r\n !Number.isFinite(renderCenterModelX) ||\r\n !Number.isFinite(renderCenterModelY)\r\n ) {\r\n warnings.push(\r\n `Viewport '${vp.id}' has non-finite transform values (centerX=${centerX}, centerY=${centerY}, mmPerModel=${mmPerModel}). Skipping render.`\r\n );\r\n return parts;\r\n }\r\n\r\n // console.log(`[DEBUG CLIP APPLY vp=\"${vp.id}\"] clipPolysLocal exists: ${!!clipPolysLocal}, length: ${clipPolysLocal?.length ?? 0}`);\r\n if (clipPolysLocal && clipPolysLocal.length) {\r\n // console.log(`[DEBUG CLIP APPLY vp=\"${vp.id}\"] *** APPLYING CLIP-PATH *** with ${clipPolysLocal.length} polygons`);\r\n if (clipPolysLocal.every((poly) => !poly.length)) {\r\n warnings.push(`Viewport '${vp.id}' clip has no points after prep; skipping clip.`);\r\n }\r\n clipId = `clip-${vp.id}-${parts.length}`;\r\n const polyPartsPage: string[] = [];\r\n // Clip polygon points are in model-view coordinates (not SVG-internal),\r\n // so transform them with outer only (model-view → page). Do NOT apply\r\n // geometryTransform — that maps SVG-internal → model-view, which is only\r\n // correct for path data inside the <g transform=\"geometryTransform\"> group.\r\n const outer = matMultiply(\r\n matTranslate(centerX, centerY),\r\n matMultiply(\r\n matRotateDeg(rotationDeg),\r\n matMultiply(matScale(mmPerModel, mmPerModel), matTranslate(-renderCenterModelX, -renderCenterModelY))\r\n )\r\n );\r\n\r\n // Debug: log clip polygon bounds\r\n let clipMinX = Infinity,\r\n clipMaxX = -Infinity,\r\n clipMinY = Infinity,\r\n clipMaxY = -Infinity;\r\n clipPolysLocal.forEach((poly) => {\r\n poly.forEach((p) => {\r\n if (p.x < clipMinX) clipMinX = p.x;\r\n if (p.x > clipMaxX) clipMaxX = p.x;\r\n if (p.y < clipMinY) clipMinY = p.y;\r\n if (p.y > clipMaxY) clipMaxY = p.y;\r\n });\r\n });\r\n // console.log(`[DEBUG CLIP vp=\"${vp.id}\"] Local bounds: x=${clipMinX.toFixed(2)}..${clipMaxX.toFixed(2)} y=${clipMinY.toFixed(2)}..${clipMaxY.toFixed(2)} (w=${(clipMaxX - clipMinX).toFixed(2)} h=${(clipMaxY - clipMinY).toFixed(2)})`);\r\n\r\n clipPolysLocal.forEach((poly) => {\r\n const pagePtsArr = poly.map((p) => matApply(outer, p));\r\n const pagePts = pagePtsArr.map((p) => `${p.x},${p.y}`).join(' ');\r\n polyPartsPage.push(`<polygon points=\"${pagePts}\" />`);\r\n if (clipStroke || clipFill) {\r\n clipDebugPolys.push(\r\n `<polygon points=\"${pagePts}\"` +\r\n (clipStroke ? ` stroke=\"${escapeAttr(clipStroke)}\"` : '') +\r\n (clipStrokeWidth ? ` stroke-width=\"${clipStrokeWidth}\"` : '') +\r\n (clipStrokeOpacity !== undefined ? ` stroke-opacity=\"${clipStrokeOpacity}\"` : '') +\r\n (clipFill ? ` fill=\"${escapeAttr(clipFill)}\"` : ' fill=\"none\"') +\r\n (clipFillOpacity !== undefined ? ` fill-opacity=\"${clipFillOpacity}\"` : '') +\r\n ` />`\r\n );\r\n }\r\n if (DEBUG_CLIP_OVERLAY) {\r\n clipDebugPolys.push(\r\n `<polygon points=\"${pagePts}\" stroke=\"#ff00ff\" stroke-width=\"0.4\" fill=\"#000000\" fill-opacity=\"0.35\" />`\r\n );\r\n }\r\n });\r\n parts.push(\r\n `<defs><clipPath id=\"${clipId}\" clipPathUnits=\"userSpaceOnUse\">${polyPartsPage.join('')}</clipPath></defs>`\r\n );\r\n }\r\n\r\n parts.push(`<g${clipId ? ` clip-path=\"url(#${clipId})\"` : ''}>`);\r\n parts.push(`<g transform=\"${transformAttr}\">`);\r\n\r\n // Render fill polygons below structural lines\r\n const allowedGids = viewportHighlight[vp.id]?.gids ?? null;\r\n const fillSvg = buildFillSvg(vp, dataWithViewport, model, allowedGids, legendColorMaps);\r\n if (fillSvg) parts.push(fillSvg);\r\n\r\n // Debug: log sample path coordinates from model.groupSvg\r\n if (clipId && model.rawPaths && model.rawPaths.length > 0) {\r\n const asMeta = (m: unknown): { isSegment?: boolean; isFill?: boolean; class?: string } | undefined =>\r\n m != null && typeof m === 'object'\r\n ? (m as { isSegment?: boolean; isFill?: boolean; class?: string })\r\n : undefined;\r\n const samplePath = model.rawPaths.find((p) => {\r\n const pm = asMeta(p.meta);\r\n return pm?.isSegment || (!pm?.isFill && !pm?.class);\r\n });\r\n if (samplePath) {\r\n const dMatch = samplePath.d.match(/M([\\d.-]+)\\s+([\\d.-]+)/);\r\n if (dMatch) {\r\n // console.log(`[DEBUG PATH vp=\"${vp.id}\"] Sample wall path starts at x=${dMatch[1]} y=${dMatch[2]} (world coords, will be transformed by geometryTransform)`);\r\n }\r\n }\r\n }\r\n\r\n // Compensate stroke-widths for the viewport scale transform.\r\n // Paths have stroke-width in model units; the scale(mmPerModel) transform\r\n // would make them thinner/thicker depending on zoom. Dividing by mmPerModel\r\n // ensures strokes render at their intended mm size regardless of viewport scale.\r\n const compensatedSvg = model.groupSvg.replace(\r\n /stroke-width=\"([0-9.eE+-]+)\"/g,\r\n (_, w) => `stroke-width=\"${parseFloat(w) / mmPerModel}\"`\r\n );\r\n parts.push(compensatedSvg);\r\n parts.push('</g>');\r\n parts.push('</g>');\r\n\r\n if (clipDebugPolys.length) {\r\n parts.push(`<g pointer-events=\"none\">${clipDebugPolys.join('')}</g>`);\r\n }\r\n\r\n viewportRenderInfo[vp.id] = {\r\n mmPerModel,\r\n contentWidthMm: rotated.width,\r\n contentHeightMm: rotated.height,\r\n offsetX: contentOffsetX,\r\n offsetY: contentOffsetY,\r\n rotationDeg,\r\n transform: model.transform!,\r\n centerX,\r\n centerY,\r\n centerModelX: renderCenterModelX,\r\n centerModelY: renderCenterModelY\r\n };\r\n\r\n if (vp.border) {\r\n const borderStroke = vp.border.stroke ?? '#000';\r\n const borderWidth = vp.border.strokeWidthMm ?? 0.25;\r\n parts.push(\r\n `<rect x=\"${vp.xMm}\" y=\"${vp.yMm}\" width=\"${vp.widthMm}\" height=\"${vp.heightMm}\" stroke=\"${escapeAttr(\r\n borderStroke\r\n )}\" stroke-width=\"${borderWidth}\" fill=\"none\"${vp.border.dashed ? ' stroke-dasharray=\"4 2\"' : ''} />`\r\n );\r\n }\r\n\r\n if (vp.northArrow) {\r\n const arrow = vp.northArrow;\r\n const asset = assetMap.get(arrow.assetId);\r\n const size = arrow.sizeMm ?? 12;\r\n const offsetX = arrow.offsetXMm ?? 8;\r\n const offsetY = arrow.offsetYMm ?? 8;\r\n const arrowX = vp.xMm + vp.widthMm - offsetX - size;\r\n const arrowY = vp.yMm + offsetY;\r\n const arrowRotation = arrow.rotationDeg ?? 0;\r\n if (!asset) {\r\n warnings.push(`Missing asset '${arrow.assetId}' for north arrow on viewport '${vp.id}'.`);\r\n } else if (asset.src) {\r\n parts.push(\r\n `<image href=\"${escapeAttr(asset.src)}\" x=\"${arrowX}\" y=\"${arrowY}\" width=\"${size}\" height=\"${size}\" transform=\"rotate(${arrowRotation}, ${arrowX + size / 2}, ${\r\n arrowY + size / 2\r\n })\" />`\r\n );\r\n } else if (asset.content) {\r\n parts.push(\r\n `<g transform=\"translate(${arrowX} ${arrowY}) rotate(${arrowRotation} ${size / 2} ${size / 2})\">${asset.content}</g>`\r\n );\r\n }\r\n }\r\n\r\n return parts;\r\n};\r\n\r\n// ---------------------------------------------------------------------------\r\n// Fill polygon rendering\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Build SVG fill polygons from viewport fill rules and item data.\r\n * Returns an SVG fragment in model-view coordinates (same space as model.groupSvg),\r\n * or null if no fills should be rendered.\r\n */\r\nfunction buildFillSvg(\r\n vp: ViewportElement,\r\n data: any,\r\n model: SvgModelView,\r\n allowedGids: Set<string> | null,\r\n legendColorMaps?: Map<string, Map<string, string>>\r\n): string | null {\r\n const fills = vp.fills;\r\n if (!fills?.length || !model.transform) return null;\r\n\r\n const items = getPathValue(data, `viewports.${vp.id}.items`);\r\n if (!Array.isArray(items) || !items.length) return null;\r\n\r\n const { viewMinX, viewMaxZ } = model.transform;\r\n const parts: string[] = [];\r\n\r\n for (const rule of fills) {\r\n const opacity = rule.fillOpacity ?? 0.35;\r\n // Find items matching this fill rule\r\n let matching = items.filter((item: unknown) =>\r\n isRecord(item) ? matchesV2Filter(item, rule.class, rule.where) : false\r\n );\r\n\r\n // Filter by allowed GIDs (from clip polygon center point test)\r\n // Only apply if BOTH: clip filtering is active AND this fill rule opts in via matchClipFilter\r\n if (allowedGids !== null && rule.matchClipFilter === true) {\r\n matching = matching.filter((item: unknown) => {\r\n const gid = getProp(item, 'gid') ?? getProp(item, 'id');\r\n return gid !== null && gid !== undefined && allowedGids.has(String(gid));\r\n });\r\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] Clip filter applied (matchClipFilter=true): ${beforeFilter} → ${matching.length} items (allowedGids.size=${allowedGids.size})`);\r\n } else if (rule.matchClipFilter === true) {\r\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] Fill rule has matchClipFilter=true but no clip polygon active`);\r\n }\r\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] Fill rule (class=\"${rule.class}\", where=${JSON.stringify(rule.where)}) matched ${matching.length} items`);\r\n // if (matching.length > 0) {\r\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] First matched item:`, {\r\n // gid: getProp(matching[0], 'gid'),\r\n // name: getProp(matching[0], 'name'),\r\n // ifcClass: getProp(matching[0], 'ifcClass'),\r\n // propertySets: getProp(matching[0], 'propertySets'),\r\n // polylines: Array.isArray(getProp(matching[0], 'polylines')) ? (getProp(matching[0], 'polylines') as any[]).length : 0\r\n // });\r\n // }\r\n if (!matching.length) continue;\r\n\r\n for (const item of matching) {\r\n const polylines = getProp(item, 'polylines');\r\n if (!Array.isArray(polylines)) continue;\r\n\r\n // Resolve fill color for this item\r\n const color = getProp(item, 'color') as [number, number, number, number] | undefined;\r\n let fillColor: string;\r\n if (rule.fill === 'sample') {\r\n if (!color) continue; // no sampled color available\r\n fillColor = `rgb(${color[0]},${color[1]},${color[2]})`;\r\n } else if (rule.fill === 'legend') {\r\n // Use color from legend color map\r\n const legendColorMap = legendColorMaps?.get(vp.id);\r\n if (!legendColorMap) {\r\n console.warn(\r\n `[FILL] fill=\"legend\" specified but no legend color map found for viewport \"${vp.id}\". Available viewports:`,\r\n Array.from(legendColorMaps?.keys() ?? [])\r\n );\r\n continue;\r\n }\r\n // Find matching legend entry - need to determine which property to use for lookup\r\n // For now, try common properties (can be made configurable later)\r\n let legendKey: string | undefined;\r\n const possibleKeys = ['spacename', 'BIP.spacename', 'name'];\r\n for (const key of possibleKeys) {\r\n const value = resolvePath(item, key);\r\n if (value !== undefined && value !== null) {\r\n legendKey = String(value);\r\n break;\r\n }\r\n }\r\n if (!legendKey || !legendColorMap.has(legendKey)) {\r\n // No matching color in legend, skip this item\r\n // if (legendKey) {\r\n // console.log(`[FILL] No color mapping for \"${legendKey}\" (property: ${matchedProperty}). Available keys:`, Array.from(legendColorMap.keys()));\r\n // }\r\n continue;\r\n }\r\n fillColor = legendColorMap.get(legendKey)!;\r\n // console.log(`[FILL] ✓ Matched \"${legendKey}\" -> ${fillColor}`);\r\n } else {\r\n fillColor = rule.fill;\r\n }\r\n\r\n // console.log(`[FILL] Processing ${polylines.length} polyline(s) for item with color ${fillColor}`);\r\n for (const polyline of polylines) {\r\n const points = isRecord(polyline) ? getProp(polyline, 'points') : null;\r\n if (!Array.isArray(points) || points.length < 3) continue;\r\n\r\n // Build path in model-view coordinates\r\n const pathParts: string[] = [];\r\n for (let i = 0; i < points.length; i++) {\r\n const pt = points[i];\r\n const px = isRecord(pt) ? getProp(pt, 'x') : null;\r\n const pz = isRecord(pt) ? getProp(pt, 'z') : null;\r\n if (!Number.isFinite(px) || !Number.isFinite(pz)) continue;\r\n const mx = (px as number) - viewMinX;\r\n const my = viewMaxZ - (pz as number);\r\n pathParts.push(i === 0 ? `M ${mx} ${my}` : `L ${mx} ${my}`);\r\n }\r\n if (pathParts.length < 3) continue;\r\n pathParts.push('Z');\r\n parts.push(\r\n `<path d=\"${pathParts.join(' ')}\" fill=\"${escapeAttr(fillColor)}\" fill-opacity=\"${opacity}\" stroke=\"none\"/>`\r\n );\r\n }\r\n }\r\n }\r\n\r\n // console.log(`[FILL] Generated ${parts.length} fill polygon(s) for viewport \"${vp.id}\"`);\r\n return parts.length ? `<g>${parts.join('')}</g>` : null;\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"viewportRender.js","sourceRoot":"/","sources":["layout/viewportRender.ts"],"names":[],"mappings":"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","sourcesContent":["import { escapeAttr, getPathValue, resolvePath } from './renderUtils';\nimport { rotateBounds, pickScale } from './viewportUtils';\nimport { ViewportRenderInfo } from './labelsRender';\nimport { matchesV2Filter } from './filters';\nimport { ComputedViewportScale, SvgModelView, ViewportElement, AssetSpec } from './types';\nimport { isRecord, getProp } from './typeGuards';\n\ntype PolyPoint = { x: number; y: number };\n// Debug overlay for clip polygons. Keep false for normal builds.\nconst DEBUG_CLIP_OVERLAY = false;\n\ntype Mat = [number, number, number, number, number, number]; // a b c d e f\n\nconst matTranslate = (tx: number, ty: number): Mat => [1, 0, 0, 1, tx, ty];\nconst matScale = (sx: number, sy: number): Mat => [sx, 0, 0, sy, 0, 0];\nconst matRotateDeg = (deg: number): Mat => {\n const rad = (deg * Math.PI) / 180;\n const c = Math.cos(rad);\n const s = Math.sin(rad);\n return [c, s, -s, c, 0, 0];\n};\nconst matMultiply = (m1: Mat, m2: Mat): Mat => {\n const [a1, b1, c1, d1, e1, f1] = m1;\n const [a2, b2, c2, d2, e2, f2] = m2;\n return [\n a1 * a2 + c1 * b2,\n b1 * a2 + d1 * b2,\n a1 * c2 + c1 * d2,\n b1 * c2 + d1 * d2,\n a1 * e2 + c1 * f2 + e1,\n b1 * e2 + d1 * f2 + f1\n ];\n};\nconst matApply = (m: Mat, p: PolyPoint): PolyPoint => {\n const [a, b, c, d, e, f] = m;\n return { x: a * p.x + c * p.y + e, y: b * p.x + d * p.y + f };\n};\nexport const renderViewportElement = (\n vp: ViewportElement,\n baseModel: SvgModelView | null,\n dataWithViewport: any,\n preferredScales: number[],\n scales: Record<string, { preferredScales?: number[] }>,\n assetMap: Map<string, AssetSpec>,\n viewportScales: Record<string, ComputedViewportScale>,\n viewportClipPolygonsLocal: Record<string, Array<Array<PolyPoint>>>,\n viewportClipBounds: Record<\n string,\n { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number }\n >,\n viewportClipLabels: Record<string, boolean>,\n viewportClipStyles: Record<\n string,\n { stroke?: string; strokeWidthMm?: number; strokeOpacity?: number; fill?: string; fillOpacity?: number }\n >,\n viewportHighlight: Record<string, { gids: Set<string> | null; styles: any }>,\n viewportRenderInfo: Record<string, ViewportRenderInfo>,\n warnings: string[],\n legendColorMaps?: Map<string, Map<string, string>>,\n precomputed?: {\n effectiveWidthModel?: number;\n effectiveHeightModel?: number;\n clipPolygonsMm?: Array<Array<PolyPoint>>;\n clipPolygonsLocal?: Array<Array<PolyPoint>>;\n clipBounds?: { minX: number; maxX: number; minY: number; maxY: number; width: number; height: number };\n renderCenterModelX?: number;\n renderCenterModelY?: number;\n }\n): string[] => {\n const parts: string[] = [];\n if (!baseModel) {\n // Warning already pushed by viewportPrep; avoid duplicate.\n return parts;\n }\n\n const model = baseModel;\n let renderWidthModel = precomputed?.effectiveWidthModel ?? model.widthModel;\n let renderHeightModel = precomputed?.effectiveHeightModel ?? model.heightModel;\n let renderCenterModelX = precomputed?.renderCenterModelX ?? renderWidthModel * 0.5;\n let renderCenterModelY = precomputed?.renderCenterModelY ?? renderHeightModel * 0.5;\n\n const clipBounds = viewportClipBounds[vp.id];\n const clipLocal = viewportClipPolygonsLocal[vp.id];\n const hasClip = !!clipBounds && Array.isArray(clipLocal) && clipLocal.length > 0;\n if (hasClip) {\n renderWidthModel = clipBounds!.width;\n renderHeightModel = clipBounds!.height;\n renderCenterModelX = (clipBounds!.minX + clipBounds!.maxX) * 0.5;\n renderCenterModelY = (clipBounds!.minY + clipBounds!.maxY) * 0.5;\n }\n\n const scaleInfo =\n viewportScales[vp.id] ??\n pickScale(\n vp,\n { ...model, widthModel: renderWidthModel, heightModel: renderHeightModel },\n preferredScales,\n scales\n );\n const rotationDeg = vp.rotationDeg ?? 0;\n const mmPerModel = scaleInfo.mmPerModelUnit;\n const contentWidthMm = renderWidthModel * mmPerModel;\n const contentHeightMm = renderHeightModel * mmPerModel;\n const rotated = rotateBounds(contentWidthMm, contentHeightMm, rotationDeg);\n\n const centerX = vp.align === 'topLeft' ? vp.xMm + rotated.width / 2 : vp.xMm + vp.widthMm / 2;\n const centerY = vp.align === 'topLeft' ? vp.yMm + rotated.height / 2 : vp.yMm + vp.heightMm / 2;\n\n const contentOffsetX = vp.align === 'topLeft' ? vp.xMm : vp.xMm + Math.max(0, (vp.widthMm - rotated.width) * 0.5);\n const contentOffsetY = vp.align === 'topLeft' ? vp.yMm : vp.yMm + Math.max(0, (vp.heightMm - rotated.height) * 0.5);\n\n const clipPolysLocal = clipLocal;\n let clipId: string | null = null;\n const clipDebugPolys: string[] = [];\n const clipStyle = viewportClipStyles[vp.id];\n const clipStroke = clipStyle?.stroke;\n const clipStrokeWidth = clipStyle?.strokeWidthMm;\n const clipStrokeOpacity = clipStyle?.strokeOpacity;\n const clipFill = clipStyle?.fill;\n const clipFillOpacity = clipStyle?.fillOpacity;\n const transformAttr = `translate(${centerX} ${centerY}) rotate(${rotationDeg}) scale(${mmPerModel}) translate(${-renderCenterModelX} ${-renderCenterModelY})`;\n\n // Debug: log model bounds and path breakdown\n // if (model.transform) {\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] Model bounds: viewMinX=${model.transform.viewMinX.toFixed(2)} viewMaxX=${model.transform.viewMaxX?.toFixed(2)} viewMinZ=${model.transform.viewMinZ.toFixed(2)} viewMaxZ=${model.transform.viewMaxZ.toFixed(2)} viewWidth=${model.transform.viewWidth.toFixed(2)} viewHeight=${model.transform.viewHeight.toFixed(2)}`);\n\n // if (model.rawPaths) {\n // const fills = model.rawPaths.filter(p => p.meta?.isFill);\n // const segments = model.rawPaths.filter(p => p.meta?.isSegment);\n // const other = model.rawPaths.filter(p => !p.meta?.isFill && !p.meta?.isSegment);\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] Path breakdown: ${model.rawPaths.length} total (${fills.length} fills, ${segments.length} segments, ${other.length} other)`);\n\n // // Sample a few segment paths\n // const sampleSegments = segments.slice(0, 3);\n // sampleSegments.forEach((seg, idx) => {\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] Segment ${idx}: class=${seg.meta?.class} fill=${seg.fill} stroke=${seg.stroke} strokeWidth=${seg.strokeWidth} d=${seg.d.substring(0, 50)}...`);\n // });\n\n // // Check if geometryTransform is present\n // if (model.geometryTransform) {\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] geometryTransform=\"${model.geometryTransform}\"`);\n // } else {\n // console.log(`[DEBUG MODEL vp=\"${vp.id}\"] WARNING: geometryTransform is MISSING!`);\n // }\n // }\n // }\n\n // Guard: detect NaN/Infinity in computed transform values\n if (\n !Number.isFinite(centerX) ||\n !Number.isFinite(centerY) ||\n !Number.isFinite(mmPerModel) ||\n !Number.isFinite(renderCenterModelX) ||\n !Number.isFinite(renderCenterModelY)\n ) {\n warnings.push(\n `Viewport '${vp.id}' has non-finite transform values (centerX=${centerX}, centerY=${centerY}, mmPerModel=${mmPerModel}). Skipping render.`\n );\n return parts;\n }\n\n // console.log(`[DEBUG CLIP APPLY vp=\"${vp.id}\"] clipPolysLocal exists: ${!!clipPolysLocal}, length: ${clipPolysLocal?.length ?? 0}`);\n if (clipPolysLocal && clipPolysLocal.length) {\n // console.log(`[DEBUG CLIP APPLY vp=\"${vp.id}\"] *** APPLYING CLIP-PATH *** with ${clipPolysLocal.length} polygons`);\n if (clipPolysLocal.every((poly) => !poly.length)) {\n warnings.push(`Viewport '${vp.id}' clip has no points after prep; skipping clip.`);\n }\n clipId = `clip-${vp.id}-${parts.length}`;\n const polyPartsPage: string[] = [];\n // Clip polygon points are in model-view coordinates (not SVG-internal),\n // so transform them with outer only (model-view → page). Do NOT apply\n // geometryTransform — that maps SVG-internal → model-view, which is only\n // correct for path data inside the <g transform=\"geometryTransform\"> group.\n const outer = matMultiply(\n matTranslate(centerX, centerY),\n matMultiply(\n matRotateDeg(rotationDeg),\n matMultiply(matScale(mmPerModel, mmPerModel), matTranslate(-renderCenterModelX, -renderCenterModelY))\n )\n );\n\n // Debug: log clip polygon bounds\n let clipMinX = Infinity,\n clipMaxX = -Infinity,\n clipMinY = Infinity,\n clipMaxY = -Infinity;\n clipPolysLocal.forEach((poly) => {\n poly.forEach((p) => {\n if (p.x < clipMinX) clipMinX = p.x;\n if (p.x > clipMaxX) clipMaxX = p.x;\n if (p.y < clipMinY) clipMinY = p.y;\n if (p.y > clipMaxY) clipMaxY = p.y;\n });\n });\n // console.log(`[DEBUG CLIP vp=\"${vp.id}\"] Local bounds: x=${clipMinX.toFixed(2)}..${clipMaxX.toFixed(2)} y=${clipMinY.toFixed(2)}..${clipMaxY.toFixed(2)} (w=${(clipMaxX - clipMinX).toFixed(2)} h=${(clipMaxY - clipMinY).toFixed(2)})`);\n\n clipPolysLocal.forEach((poly) => {\n const pagePtsArr = poly.map((p) => matApply(outer, p));\n const pagePts = pagePtsArr.map((p) => `${p.x},${p.y}`).join(' ');\n polyPartsPage.push(`<polygon points=\"${pagePts}\" />`);\n if (clipStroke || clipFill) {\n clipDebugPolys.push(\n `<polygon points=\"${pagePts}\"` +\n (clipStroke ? ` stroke=\"${escapeAttr(clipStroke)}\"` : '') +\n (clipStrokeWidth ? ` stroke-width=\"${clipStrokeWidth}\"` : '') +\n (clipStrokeOpacity !== undefined ? ` stroke-opacity=\"${clipStrokeOpacity}\"` : '') +\n (clipFill ? ` fill=\"${escapeAttr(clipFill)}\"` : ' fill=\"none\"') +\n (clipFillOpacity !== undefined ? ` fill-opacity=\"${clipFillOpacity}\"` : '') +\n ` />`\n );\n }\n if (DEBUG_CLIP_OVERLAY) {\n clipDebugPolys.push(\n `<polygon points=\"${pagePts}\" stroke=\"#ff00ff\" stroke-width=\"0.4\" fill=\"#000000\" fill-opacity=\"0.35\" />`\n );\n }\n });\n parts.push(\n `<defs><clipPath id=\"${clipId}\" clipPathUnits=\"userSpaceOnUse\">${polyPartsPage.join('')}</clipPath></defs>`\n );\n }\n\n parts.push(`<g${clipId ? ` clip-path=\"url(#${clipId})\"` : ''}>`);\n parts.push(`<g transform=\"${transformAttr}\">`);\n\n // Render fill polygons below structural lines\n const allowedGids = viewportHighlight[vp.id]?.gids ?? null;\n const fillSvg = buildFillSvg(vp, dataWithViewport, model, allowedGids, legendColorMaps);\n if (fillSvg) parts.push(fillSvg);\n\n // Debug: log sample path coordinates from model.groupSvg\n if (clipId && model.rawPaths && model.rawPaths.length > 0) {\n const asMeta = (m: unknown): { isSegment?: boolean; isFill?: boolean; class?: string } | undefined =>\n m != null && typeof m === 'object'\n ? (m as { isSegment?: boolean; isFill?: boolean; class?: string })\n : undefined;\n const samplePath = model.rawPaths.find((p) => {\n const pm = asMeta(p.meta);\n return pm?.isSegment || (!pm?.isFill && !pm?.class);\n });\n if (samplePath) {\n const dMatch = samplePath.d.match(/M([\\d.-]+)\\s+([\\d.-]+)/);\n if (dMatch) {\n // console.log(`[DEBUG PATH vp=\"${vp.id}\"] Sample wall path starts at x=${dMatch[1]} y=${dMatch[2]} (world coords, will be transformed by geometryTransform)`);\n }\n }\n }\n\n // Compensate stroke-widths for the viewport scale transform.\n // Paths have stroke-width in model units; the scale(mmPerModel) transform\n // would make them thinner/thicker depending on zoom. Dividing by mmPerModel\n // ensures strokes render at their intended mm size regardless of viewport scale.\n const compensatedSvg = model.groupSvg.replace(\n /stroke-width=\"([0-9.eE+-]+)\"/g,\n (_, w) => `stroke-width=\"${parseFloat(w) / mmPerModel}\"`\n );\n parts.push(compensatedSvg);\n parts.push('</g>');\n parts.push('</g>');\n\n if (clipDebugPolys.length) {\n parts.push(`<g pointer-events=\"none\">${clipDebugPolys.join('')}</g>`);\n }\n\n viewportRenderInfo[vp.id] = {\n mmPerModel,\n contentWidthMm: rotated.width,\n contentHeightMm: rotated.height,\n offsetX: contentOffsetX,\n offsetY: contentOffsetY,\n rotationDeg,\n transform: model.transform!,\n centerX,\n centerY,\n centerModelX: renderCenterModelX,\n centerModelY: renderCenterModelY\n };\n\n if (vp.border) {\n const borderStroke = vp.border.stroke ?? '#000';\n const borderWidth = vp.border.strokeWidthMm ?? 0.25;\n parts.push(\n `<rect x=\"${vp.xMm}\" y=\"${vp.yMm}\" width=\"${vp.widthMm}\" height=\"${vp.heightMm}\" stroke=\"${escapeAttr(\n borderStroke\n )}\" stroke-width=\"${borderWidth}\" fill=\"none\"${vp.border.dashed ? ' stroke-dasharray=\"4 2\"' : ''} />`\n );\n }\n\n if (vp.northArrow) {\n const arrow = vp.northArrow;\n const asset = assetMap.get(arrow.assetId);\n const size = arrow.sizeMm ?? 12;\n const offsetX = arrow.offsetXMm ?? 8;\n const offsetY = arrow.offsetYMm ?? 8;\n const arrowX = vp.xMm + vp.widthMm - offsetX - size;\n const arrowY = vp.yMm + offsetY;\n const arrowRotation = arrow.rotationDeg ?? 0;\n if (!asset) {\n warnings.push(`Missing asset '${arrow.assetId}' for north arrow on viewport '${vp.id}'.`);\n } else if (asset.src) {\n parts.push(\n `<image href=\"${escapeAttr(asset.src)}\" x=\"${arrowX}\" y=\"${arrowY}\" width=\"${size}\" height=\"${size}\" transform=\"rotate(${arrowRotation}, ${arrowX + size / 2}, ${\n arrowY + size / 2\n })\" />`\n );\n } else if (asset.content) {\n parts.push(\n `<g transform=\"translate(${arrowX} ${arrowY}) rotate(${arrowRotation} ${size / 2} ${size / 2})\">${asset.content}</g>`\n );\n }\n }\n\n return parts;\n};\n\n// ---------------------------------------------------------------------------\n// Fill polygon rendering\n// ---------------------------------------------------------------------------\n\n/**\n * Build SVG fill polygons from viewport fill rules and item data.\n * Returns an SVG fragment in model-view coordinates (same space as model.groupSvg),\n * or null if no fills should be rendered.\n */\nfunction buildFillSvg(\n vp: ViewportElement,\n data: any,\n model: SvgModelView,\n allowedGids: Set<string> | null,\n legendColorMaps?: Map<string, Map<string, string>>\n): string | null {\n const fills = vp.fills;\n if (!fills?.length || !model.transform) return null;\n\n const items = getPathValue(data, `viewports.${vp.id}.items`);\n if (!Array.isArray(items) || !items.length) return null;\n\n const { viewMinX, viewMaxZ } = model.transform;\n const parts: string[] = [];\n\n for (const rule of fills) {\n const opacity = rule.fillOpacity ?? 0.35;\n // Find items matching this fill rule\n let matching = items.filter((item: unknown) =>\n isRecord(item) ? matchesV2Filter(item, rule.class, rule.where) : false\n );\n\n // Filter by allowed GIDs (from clip polygon center point test)\n // Only apply if BOTH: clip filtering is active AND this fill rule opts in via matchClipFilter\n if (allowedGids !== null && rule.matchClipFilter === true) {\n matching = matching.filter((item: unknown) => {\n const gid = getProp(item, 'gid') ?? getProp(item, 'id');\n return gid !== null && gid !== undefined && allowedGids.has(String(gid));\n });\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] Clip filter applied (matchClipFilter=true): ${beforeFilter} → ${matching.length} items (allowedGids.size=${allowedGids.size})`);\n } else if (rule.matchClipFilter === true) {\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] Fill rule has matchClipFilter=true but no clip polygon active`);\n }\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] Fill rule (class=\"${rule.class}\", where=${JSON.stringify(rule.where)}) matched ${matching.length} items`);\n // if (matching.length > 0) {\n // console.log(`[DEBUG FILL vp=\"${vp.id}\"] First matched item:`, {\n // gid: getProp(matching[0], 'gid'),\n // name: getProp(matching[0], 'name'),\n // ifcClass: getProp(matching[0], 'ifcClass'),\n // propertySets: getProp(matching[0], 'propertySets'),\n // polylines: Array.isArray(getProp(matching[0], 'polylines')) ? (getProp(matching[0], 'polylines') as any[]).length : 0\n // });\n // }\n if (!matching.length) continue;\n\n for (const item of matching) {\n const polylines = getProp(item, 'polylines');\n if (!Array.isArray(polylines)) continue;\n\n // Resolve fill color for this item\n const color = getProp(item, 'color') as [number, number, number, number] | undefined;\n let fillColor: string;\n if (rule.fill === 'sample') {\n if (!color) continue; // no sampled color available\n fillColor = `rgb(${color[0]},${color[1]},${color[2]})`;\n } else if (rule.fill === 'legend') {\n // Use color from legend color map\n const legendColorMap = legendColorMaps?.get(vp.id);\n if (!legendColorMap) {\n console.warn(\n `[FILL] fill=\"legend\" specified but no legend color map found for viewport \"${vp.id}\". Available viewports:`,\n Array.from(legendColorMaps?.keys() ?? [])\n );\n continue;\n }\n // Find matching legend entry - need to determine which property to use for lookup\n // For now, try common properties (can be made configurable later)\n let legendKey: string | undefined;\n const possibleKeys = ['spacename', 'BIP.spacename', 'name'];\n for (const key of possibleKeys) {\n const value = resolvePath(item, key);\n if (value !== undefined && value !== null) {\n legendKey = String(value);\n break;\n }\n }\n if (!legendKey || !legendColorMap.has(legendKey)) {\n // No matching color in legend, skip this item\n // if (legendKey) {\n // console.log(`[FILL] No color mapping for \"${legendKey}\" (property: ${matchedProperty}). Available keys:`, Array.from(legendColorMap.keys()));\n // }\n continue;\n }\n fillColor = legendColorMap.get(legendKey)!;\n // console.log(`[FILL] ✓ Matched \"${legendKey}\" -> ${fillColor}`);\n } else {\n fillColor = rule.fill;\n }\n\n // console.log(`[FILL] Processing ${polylines.length} polyline(s) for item with color ${fillColor}`);\n for (const polyline of polylines) {\n const points = isRecord(polyline) ? getProp(polyline, 'points') : null;\n if (!Array.isArray(points) || points.length < 3) continue;\n\n // Build path in model-view coordinates\n const pathParts: string[] = [];\n for (let i = 0; i < points.length; i++) {\n const pt = points[i];\n const px = isRecord(pt) ? getProp(pt, 'x') : null;\n const pz = isRecord(pt) ? getProp(pt, 'z') : null;\n if (!Number.isFinite(px) || !Number.isFinite(pz)) continue;\n const mx = (px as number) - viewMinX;\n const my = viewMaxZ - (pz as number);\n pathParts.push(i === 0 ? `M ${mx} ${my}` : `L ${mx} ${my}`);\n }\n if (pathParts.length < 3) continue;\n pathParts.push('Z');\n parts.push(\n `<path d=\"${pathParts.join(' ')}\" fill=\"${escapeAttr(fillColor)}\" fill-opacity=\"${opacity}\" stroke=\"none\"/>`\n );\n }\n }\n }\n\n // console.log(`[FILL] Generated ${parts.length} fill polygon(s) for viewport \"${vp.id}\"`);\n return parts.length ? `<g>${parts.join('')}</g>` : null;\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"viewportUtils.js","sourceRoot":"/","sources":["layout/viewportUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAG/C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,MAAc,EAAE,WAAmB,EAAqC,EAAE;IAClH,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3C,MAAM,GAAG,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IACrE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CACrB,QAAyB,EACzB,KAAmB,EACnB,SAAmB,EACnB,YAA4D,EACvC,EAAE;IACvB,MAAM,eAAe,GAAG,QAAQ,CAAC,WAAW,CAAC;IAC7C,MAAM,WAAW,GAAG,eAAe,IAAI,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5G,MAAM,MAAM,GACR,QAAQ,CAAC,SAAS,KAAK,OAAO,IAAI,QAAQ,CAAC,eAAe;QACtD,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC5B,CAAC,CAAC,oBAAoB,CAAC,QAAQ,CAAC,eAAe,IAAI,WAAW,EAAE,eAAe,IAAI,SAAS,CAAC,CAAC;IAEtG,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;IAC9C,IAAI,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9C,IAAI,kBAAkB,GAAG,IAAI,GAAG,aAAa,CAAC;IAC9C,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,GAAG,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC;QAChD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC3E,aAAa,GAAG,KAAK,CAAC;YACtB,kBAAkB,GAAG,UAAU,CAAC;YAChC,IAAI,GAAG,IAAI,CAAC;YACZ,MAAM;QACV,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,EAAE,aAAa;QACpB,cAAc,EAAE,kBAAkB;QAClC,IAAI;KACP,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { uniquePositiveDenoms } from './utils';\
|
|
1
|
+
{"version":3,"file":"viewportUtils.js","sourceRoot":"/","sources":["layout/viewportUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAC;AAG/C,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,KAAa,EAAE,MAAc,EAAE,WAAmB,EAAqC,EAAE;IAClH,IAAI,CAAC,WAAW;QAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC;IAC3C,MAAM,GAAG,GAAG,CAAC,WAAW,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC;IAC1C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IAC1B,MAAM,YAAY,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IACpE,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC;IACrE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,CAAC;AAC1D,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,CACrB,QAAyB,EACzB,KAAmB,EACnB,SAAmB,EACnB,YAA4D,EACvC,EAAE;IACvB,MAAM,eAAe,GAAG,QAAQ,CAAC,WAAW,CAAC;IAC7C,MAAM,WAAW,GAAG,eAAe,IAAI,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5G,MAAM,MAAM,GACR,QAAQ,CAAC,SAAS,KAAK,OAAO,IAAI,QAAQ,CAAC,eAAe;QACtD,CAAC,CAAC,CAAC,QAAQ,CAAC,eAAe,CAAC;QAC5B,CAAC,CAAC,oBAAoB,CAAC,QAAQ,CAAC,eAAe,IAAI,WAAW,EAAE,eAAe,IAAI,SAAS,CAAC,CAAC;IAEtG,MAAM,WAAW,GAAG,QAAQ,CAAC,WAAW,IAAI,CAAC,CAAC;IAC9C,IAAI,aAAa,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC9C,IAAI,kBAAkB,GAAG,IAAI,GAAG,aAAa,CAAC;IAC9C,IAAI,IAAI,GAAG,KAAK,CAAC;IAEjB,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QACzB,MAAM,UAAU,GAAG,IAAI,GAAG,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,UAAU,GAAG,UAAU,CAAC;QAC9C,MAAM,QAAQ,GAAG,KAAK,CAAC,WAAW,GAAG,UAAU,CAAC;QAChD,MAAM,OAAO,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,WAAW,CAAC,CAAC;QAC7D,IAAI,OAAO,CAAC,KAAK,IAAI,QAAQ,CAAC,OAAO,IAAI,OAAO,CAAC,MAAM,IAAI,QAAQ,CAAC,QAAQ,EAAE,CAAC;YAC3E,aAAa,GAAG,KAAK,CAAC;YACtB,kBAAkB,GAAG,UAAU,CAAC;YAChC,IAAI,GAAG,IAAI,CAAC;YACZ,MAAM;QACV,CAAC;IACL,CAAC;IAED,OAAO;QACH,KAAK,EAAE,aAAa;QACpB,cAAc,EAAE,kBAAkB;QAClC,IAAI;KACP,CAAC;AACN,CAAC,CAAC","sourcesContent":["import { uniquePositiveDenoms } from './utils';\nimport { ComputedViewportScale, SvgModelView, ViewportElement } from './types';\n\nexport const rotateBounds = (width: number, height: number, rotationDeg: number): { width: number; height: number } => {\n if (!rotationDeg) return { width, height };\n const rad = (rotationDeg * Math.PI) / 180;\n const cos = Math.cos(rad);\n const sin = Math.sin(rad);\n const rotatedWidth = Math.abs(width * cos) + Math.abs(height * sin);\n const rotatedHeight = Math.abs(width * sin) + Math.abs(height * cos);\n return { width: rotatedWidth, height: rotatedHeight };\n};\n\nexport const pickScale = (\n viewport: ViewportElement,\n model: SvgModelView,\n preferred: number[],\n scalePresets: Record<string, { preferredScales?: number[] }>\n): ComputedViewportScale => {\n const scalePresetName = viewport.scalePreset;\n const scalePreset = scalePresetName && scalePresets[scalePresetName] ? scalePresets[scalePresetName] : null;\n const denoms =\n viewport.scaleMode === 'fixed' && viewport.fixedScaleDenom\n ? [viewport.fixedScaleDenom]\n : uniquePositiveDenoms(viewport.preferredScales ?? scalePreset?.preferredScales ?? preferred);\n\n const rotationDeg = viewport.rotationDeg ?? 0;\n let selectedDenom = denoms[denoms.length - 1];\n let selectedMmPerModel = 1000 / selectedDenom;\n let fits = false;\n\n for (const denom of denoms) {\n const mmPerModel = 1000 / denom;\n const widthMm = model.widthModel * mmPerModel;\n const heightMm = model.heightModel * mmPerModel;\n const rotated = rotateBounds(widthMm, heightMm, rotationDeg);\n if (rotated.width <= viewport.widthMm && rotated.height <= viewport.heightMm) {\n selectedDenom = denom;\n selectedMmPerModel = mmPerModel;\n fits = true;\n break;\n }\n }\n\n return {\n denom: selectedDenom,\n mmPerModelUnit: selectedMmPerModel,\n fits\n };\n};\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"warnings.js","sourceRoot":"/","sources":["layout/warnings.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAkB,EAAE,OAAe,EAAQ,EAAE;IACrE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC,CAAC","sourcesContent":["export const pushWarning = (warnings: string[], message: string): void => {\
|
|
1
|
+
{"version":3,"file":"warnings.js","sourceRoot":"/","sources":["layout/warnings.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,QAAkB,EAAE,OAAe,EAAQ,EAAE;IACrE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AAC3B,CAAC,CAAC","sourcesContent":["export const pushWarning = (warnings: string[], message: string): void => {\n warnings.push(message);\n};\n"]}
|
package/dist/printToPdf.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printToPdf.js","sourceRoot":"/","sources":["printToPdf.ts"],"names":[],"mappings":"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","sourcesContent":["/**\
|
|
1
|
+
{"version":3,"file":"printToPdf.js","sourceRoot":"/","sources":["printToPdf.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAUH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,OAA0B;IACvD,2FAA2F;IAC3F,IAAI,WAAgB,CAAC;IACrB,IAAI,CAAC;QACD,kEAAkE;QAClE,WAAW,GAAG,MAAM,MAAM,CAAC,OAAO,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACL,MAAM,IAAI,KAAK,CAAC,6DAA6D,CAAC,CAAC;IACnF,CAAC;IACD,IAAI,CAAC;QACD,kEAAkE;QAClE,MAAM,MAAM,CAAC,YAAY,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACL,MAAM,IAAI,KAAK,CAAC,uEAAuE,CAAC,CAAC;IAC7F,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW,CAAC;IAC9B,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,IAAI,IAAI,CAAC;IAC1C,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,WAAW,CAAC;IACvD,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC;IAEtC,MAAM,GAAG,GAAG,IAAI,KAAK,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3D,MAAM,SAAS,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,EAAE,CAAC;IACnD,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;IAErD,MAAM,MAAM,GAAG,IAAI,SAAS,EAAE,CAAC;IAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,SAAS,EAAE,eAAe,CAAC,CAAC;IAC1E,MAAM,UAAU,GAAG,MAAM,CAAC,eAAe,CAAC;IAE1C,MAAM,GAAG,CAAC,GAAG,CAAC,UAAU,EAAE;QACtB,CAAC,EAAE,MAAM;QACT,CAAC,EAAE,MAAM;QACT,KAAK,EAAE,SAAS,GAAG,MAAM,GAAG,CAAC;QAC7B,MAAM,EAAE,UAAU,GAAG,MAAM,GAAG,CAAC;KAClC,CAAC,CAAC;IAEH,MAAM,IAAI,GAAG,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAEhC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACnB,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC/B,CAAC;IAED,OAAO,IAAI,CAAC;AAChB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,cAAc,CAAC,SAAiB,EAAE,QAAgB;IAC9D,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;IAC9D,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;IACtC,MAAM,IAAI,GAAG,QAAQ,CAAC,aAAa,CAAC,GAAG,CAAC,CAAC;IACzC,IAAI,CAAC,IAAI,GAAG,GAAG,CAAC;IAChB,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACzB,IAAI,CAAC,KAAK,EAAE,CAAC;IACb,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,CAAC;AAC7B,CAAC;AAUD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,OAAkC;IACvE,MAAM,UAAU,CAAC;QACb,SAAS,EAAE,OAAO,CAAC,SAAS;QAC5B,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC7B,CAAC,CAAC;AACP,CAAC;AAQD,MAAM,UAAU,kBAAkB,CAAC,OAAkC;IACjE,IAAI,OAAO,CAAC,YAAY,EAAE,CAAC;QACvB,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,CAAC;QACtE,MAAM,GAAG,GAAG,GAAG,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC3B,6DAA6D;QAC7D,UAAU,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,KAAM,CAAC,CAAC;IACvD,CAAC;SAAM,CAAC;QACJ,cAAc,CAAC,OAAO,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxD,CAAC;AACL,CAAC","sourcesContent":["/**\n * PDF export via jsPDF + svg2pdf.js\n *\n * These are optional peer dependencies. Functions will throw at runtime if not installed.\n */\n\nexport interface PrintToPdfOptions {\n svgMarkup: string;\n fileName?: string;\n pageFormat?: 'a0' | 'a1' | 'a2' | 'a3' | 'a4';\n orientation?: 'portrait' | 'landscape';\n marginMm?: number;\n}\n\n/**\n * Export an SVG string to a PDF file.\n * Requires jspdf and svg2pdf.js as peer dependencies.\n */\nexport async function printToPdf(options: PrintToPdfOptions): Promise<Blob> {\n // Dynamic imports for optional peer dependencies (installed by consumer, not this package)\n let jspdfModule: any;\n try {\n // @ts-expect-error — optional peer dependency resolved at runtime\n jspdfModule = await import('jspdf');\n } catch {\n throw new Error('jspdf is required for PDF export. Install it: bun add jspdf');\n }\n try {\n // @ts-expect-error — optional peer dependency resolved at runtime\n await import('svg2pdf.js');\n } catch {\n throw new Error('svg2pdf.js is required for PDF export. Install it: bun add svg2pdf.js');\n }\n\n const { jsPDF } = jspdfModule;\n const format = options.pageFormat ?? 'a3';\n const orientation = options.orientation ?? 'landscape';\n const margin = options.marginMm ?? 10;\n\n const doc = new jsPDF({ format, orientation, unit: 'mm' });\n const pageWidth = doc.internal.pageSize.getWidth();\n const pageHeight = doc.internal.pageSize.getHeight();\n\n const parser = new DOMParser();\n const svgDoc = parser.parseFromString(options.svgMarkup, 'image/svg+xml');\n const svgElement = svgDoc.documentElement;\n\n await doc.svg(svgElement, {\n x: margin,\n y: margin,\n width: pageWidth - margin * 2,\n height: pageHeight - margin * 2\n });\n\n const blob = doc.output('blob');\n\n if (options.fileName) {\n doc.save(options.fileName);\n }\n\n return blob;\n}\n\n/**\n * Export an SVG string directly as a downloadable SVG file.\n */\nexport function printToSvgFile(svgMarkup: string, fileName: string): void {\n const blob = new Blob([svgMarkup], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n const link = document.createElement('a');\n link.href = url;\n link.download = fileName;\n link.click();\n URL.revokeObjectURL(url);\n}\n\n// Compatibility wrappers for print-layout module\nexport interface ExportSectionToPdfOptions {\n svgMarkup: string;\n fileName: string;\n pageSizeMm?: { width: number; height: number };\n openInNewTab?: boolean;\n}\n\nexport async function exportSectionToPdf(options: ExportSectionToPdfOptions): Promise<void> {\n await printToPdf({\n svgMarkup: options.svgMarkup,\n fileName: options.fileName\n });\n}\n\nexport interface ExportSectionToSvgOptions {\n svgMarkup: string;\n fileName: string;\n openInNewTab?: boolean;\n}\n\nexport function exportSectionToSvg(options: ExportSectionToSvgOptions): void {\n if (options.openInNewTab) {\n const blob = new Blob([options.svgMarkup], { type: 'image/svg+xml' });\n const url = URL.createObjectURL(blob);\n window.open(url, '_blank');\n // Revoke after a delay to allow the new tab to load the blob\n setTimeout(() => URL.revokeObjectURL(url), 60_000);\n } else {\n printToSvgFile(options.svgMarkup, options.fileName);\n }\n}\n"]}
|
package/dist/printToSvg.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"printToSvg.js","sourceRoot":"/","sources":["printToSvg.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SlabSectionGeometry, Vec3 } from '@twinfinity/geometry';\r\nimport type { PrintToSvgOptions, SvgRenderStyles, SvgPlaneBasis } from './types';\r\nimport { DEFAULT_SVG_STYLES } from './types';\r\n\r\ntype Pt2 = { x: number; y: number };\r\ntype Bounds = { minX: number; maxX: number; minY: number; maxY: number };\r\n\r\n/**\r\n * Render SlabSectionGeometry to an SVG string.\r\n *\r\n * @param geometry The computed slab section geometry\r\n * @param options Rendering options (viewBox, styles, planeBasis, etc.)\r\n * @returns Complete SVG string\r\n */\r\nexport function printToSvg(geometry: SlabSectionGeometry, options: PrintToSvgOptions = {}): string {\r\n if (!geometry) throw new Error('geometry is required');\r\n\r\n if (\r\n options.boundsPadding !== undefined &&\r\n (typeof options.boundsPadding !== 'number' || options.boundsPadding < 0)\r\n ) {\r\n throw new Error('boundsPadding must be a non-negative number');\r\n }\r\n\r\n if (options.viewBox) {\r\n if (!Array.isArray(options.viewBox) || options.viewBox.length !== 4) {\r\n throw new Error('viewBox must be an array of 4 numbers [minX, minY, width, height]');\r\n }\r\n for (let i = 0; i < 4; i++) {\r\n if (typeof options.viewBox[i] !== 'number' || !Number.isFinite(options.viewBox[i])) {\r\n throw new Error(`viewBox[${i}] must be a finite number`);\r\n }\r\n }\r\n }\r\n\r\n const styles = mergeStyles(options.styles);\r\n const includeXml = options.includeXmlDeclaration ?? true;\r\n\r\n // Project all polylines to 2D once\r\n const proj = {\r\n hiddenLines: projectPolylines(geometry.hiddenLines, options.planeBasis),\r\n outlineHidden: projectPolylines(geometry.outlineHidden, options.planeBasis),\r\n visibleLines: projectPolylines(geometry.visibleLines, options.planeBasis),\r\n outlineVisible: projectPolylines(geometry.outlineVisible, options.planeBasis),\r\n silhouettes: projectPolylines(geometry.silhouettes, options.planeBasis),\r\n featureEdges: projectPolylines(geometry.featureEdges, options.planeBasis),\r\n cutLines: projectPolylines(geometry.cutLines, options.planeBasis),\r\n stairArrows: projectPolylines(geometry.stairArrows, options.planeBasis)\r\n };\r\n\r\n const bounds = options.bounds ?? computeBoundsFromProjected(proj);\r\n const viewBox = options.viewBox ?? boundsToViewBox(bounds, options.boundsPadding ?? 0.05);\r\n\r\n const parts: string[] = [];\r\n\r\n if (includeXml) parts.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\r\n\r\n const [minX, minY, width, height] = viewBox;\r\n parts.push(\r\n `<svg xmlns=\"http://www.w3.org/2000/svg\" ` +\r\n `viewBox=\"${minX} ${minY} ${width} ${height}\" ` +\r\n `width=\"${width}\" height=\"${height}\">`\r\n );\r\n\r\n if (options.backgroundColor) {\r\n parts.push(\r\n `<rect x=\"${minX}\" y=\"${minY}\" width=\"${width}\" height=\"${height}\" fill=\"${options.backgroundColor}\"/>`\r\n );\r\n }\r\n\r\n parts.push('<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">');\r\n\r\n const categories: Array<[keyof typeof proj, keyof Required<SvgRenderStyles>]> = [\r\n ['hiddenLines', 'hiddenLines'],\r\n ['outlineHidden', 'outlineHidden'],\r\n ['visibleLines', 'visibleLines'],\r\n ['outlineVisible', 'outlineVisible'],\r\n ['silhouettes', 'silhouettes'],\r\n ['featureEdges', 'featureEdges'],\r\n ['cutLines', 'cutLines'],\r\n ['stairArrows', 'stairArrows']\r\n ];\r\n\r\n for (const [key, styleKey] of categories) {\r\n const style = styles[styleKey];\r\n if (style.enabled) renderProjectedCategory(parts, proj[key], style, bounds);\r\n }\r\n\r\n parts.push('</g>');\r\n parts.push('</svg>');\r\n return parts.join('\\n');\r\n}\r\n\r\nfunction projectPolylines(polylines: Vec3[][], planeBasis?: SvgPlaneBasis): Pt2[][] {\r\n const result: Pt2[][] = [];\r\n for (const polyline of polylines) {\r\n if (polyline.length === 0) continue;\r\n const projected: Pt2[] = [];\r\n for (const point of polyline) {\r\n if (!Number.isFinite(point[0]) || !Number.isFinite(point[1]) || !Number.isFinite(point[2])) continue;\r\n if (planeBasis) {\r\n const dx = point[0] - planeBasis.origin.x;\r\n const dy = point[1] - planeBasis.origin.y;\r\n const dz = point[2] - planeBasis.origin.z;\r\n projected.push({\r\n x: dx * planeBasis.right.x + dy * planeBasis.right.y + dz * planeBasis.right.z,\r\n y: dx * planeBasis.up.x + dy * planeBasis.up.y + dz * planeBasis.up.z\r\n });\r\n } else {\r\n projected.push({ x: point[0], y: -point[2] });\r\n }\r\n }\r\n if (projected.length > 0) result.push(projected);\r\n }\r\n return result;\r\n}\r\n\r\nfunction computeBoundsFromProjected(categories: Record<string, Pt2[][]>): Bounds {\r\n let minX = Infinity,\r\n minY = Infinity,\r\n maxX = -Infinity,\r\n maxY = -Infinity;\r\n for (const polylines of Object.values(categories)) {\r\n for (const polyline of polylines) {\r\n for (const pt of polyline) {\r\n if (pt.x < minX) minX = pt.x;\r\n if (pt.x > maxX) maxX = pt.x;\r\n if (pt.y < minY) minY = pt.y;\r\n if (pt.y > maxY) maxY = pt.y;\r\n }\r\n }\r\n }\r\n if (!Number.isFinite(minX)) return { minX: 0, maxX: 1, minY: 0, maxY: 1 };\r\n return { minX, maxX, minY, maxY };\r\n}\r\n\r\nfunction renderProjectedCategory(\r\n parts: string[],\r\n polylines: Pt2[][],\r\n style: { stroke?: string; strokeWidth?: number; strokeDasharray?: string; opacity?: number },\r\n bounds: Bounds\r\n): void {\r\n if (!polylines.length) return;\r\n const pathData = projectedToPathData(polylines, bounds);\r\n if (!pathData) return;\r\n\r\n let pathElement = `<path d=\"${pathData}\"`;\r\n if (style.stroke) pathElement += ` stroke=\"${style.stroke}\"`;\r\n if (style.strokeWidth !== undefined) pathElement += ` stroke-width=\"${style.strokeWidth}\"`;\r\n if (style.strokeDasharray) pathElement += ` stroke-dasharray=\"${style.strokeDasharray}\"`;\r\n if (style.opacity !== undefined && style.opacity !== 1) pathElement += ` opacity=\"${style.opacity}\"`;\r\n pathElement += '/>';\r\n parts.push(pathElement);\r\n}\r\n\r\nfunction projectedToPathData(polylines: Pt2[][], bounds: Bounds): string {\r\n const parts: string[] = [];\r\n const ox = bounds.minX;\r\n const oy = bounds.maxY;\r\n for (const polyline of polylines) {\r\n if (polyline.length === 0) continue;\r\n parts.push(`M ${(polyline[0].x - ox).toFixed(6)} ${(oy - polyline[0].y).toFixed(6)}`);\r\n for (let i = 1; i < polyline.length; i++) {\r\n parts.push(`L ${(polyline[i].x - ox).toFixed(6)} ${(oy - polyline[i].y).toFixed(6)}`);\r\n }\r\n }\r\n return parts.join(' ');\r\n}\r\n\r\nfunction boundsToViewBox(bounds: Bounds, padding: number): [number, number, number, number] {\r\n const width = bounds.maxX - bounds.minX;\r\n const height = bounds.maxY - bounds.minY;\r\n const padAmount = Math.max(width, height) * padding;\r\n return [-padAmount, -padAmount, width + padAmount * 2, height + padAmount * 2];\r\n}\r\n\r\nfunction mergeStyles(userStyles?: SvgRenderStyles): Required<SvgRenderStyles> {\r\n return {\r\n cutLines: { ...DEFAULT_SVG_STYLES.cutLines, ...userStyles?.cutLines },\r\n visibleLines: { ...DEFAULT_SVG_STYLES.visibleLines, ...userStyles?.visibleLines },\r\n hiddenLines: { ...DEFAULT_SVG_STYLES.hiddenLines, ...userStyles?.hiddenLines },\r\n silhouettes: { ...DEFAULT_SVG_STYLES.silhouettes, ...userStyles?.silhouettes },\r\n featureEdges: { ...DEFAULT_SVG_STYLES.featureEdges, ...userStyles?.featureEdges },\r\n stairArrows: { ...DEFAULT_SVG_STYLES.stairArrows, ...userStyles?.stairArrows },\r\n outlineVisible: { ...DEFAULT_SVG_STYLES.outlineVisible, ...userStyles?.outlineVisible },\r\n outlineHidden: { ...DEFAULT_SVG_STYLES.outlineHidden, ...userStyles?.outlineHidden }\r\n };\r\n}\r\n"]}
|
|
1
|
+
{"version":3,"file":"printToSvg.js","sourceRoot":"/","sources":["printToSvg.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SlabSectionGeometry, Vec3 } from '@twinfinity/geometry';\nimport type { PrintToSvgOptions, SvgRenderStyles, SvgPlaneBasis } from './types';\nimport { DEFAULT_SVG_STYLES } from './types';\n\ntype Pt2 = { x: number; y: number };\ntype Bounds = { minX: number; maxX: number; minY: number; maxY: number };\n\n/**\n * Render SlabSectionGeometry to an SVG string.\n *\n * @param geometry The computed slab section geometry\n * @param options Rendering options (viewBox, styles, planeBasis, etc.)\n * @returns Complete SVG string\n */\nexport function printToSvg(geometry: SlabSectionGeometry, options: PrintToSvgOptions = {}): string {\n if (!geometry) throw new Error('geometry is required');\n\n if (\n options.boundsPadding !== undefined &&\n (typeof options.boundsPadding !== 'number' || options.boundsPadding < 0)\n ) {\n throw new Error('boundsPadding must be a non-negative number');\n }\n\n if (options.viewBox) {\n if (!Array.isArray(options.viewBox) || options.viewBox.length !== 4) {\n throw new Error('viewBox must be an array of 4 numbers [minX, minY, width, height]');\n }\n for (let i = 0; i < 4; i++) {\n if (typeof options.viewBox[i] !== 'number' || !Number.isFinite(options.viewBox[i])) {\n throw new Error(`viewBox[${i}] must be a finite number`);\n }\n }\n }\n\n const styles = mergeStyles(options.styles);\n const includeXml = options.includeXmlDeclaration ?? true;\n\n // Project all polylines to 2D once\n const proj = {\n hiddenLines: projectPolylines(geometry.hiddenLines, options.planeBasis),\n outlineHidden: projectPolylines(geometry.outlineHidden, options.planeBasis),\n visibleLines: projectPolylines(geometry.visibleLines, options.planeBasis),\n outlineVisible: projectPolylines(geometry.outlineVisible, options.planeBasis),\n silhouettes: projectPolylines(geometry.silhouettes, options.planeBasis),\n featureEdges: projectPolylines(geometry.featureEdges, options.planeBasis),\n cutLines: projectPolylines(geometry.cutLines, options.planeBasis),\n stairArrows: projectPolylines(geometry.stairArrows, options.planeBasis)\n };\n\n const bounds = options.bounds ?? computeBoundsFromProjected(proj);\n const viewBox = options.viewBox ?? boundsToViewBox(bounds, options.boundsPadding ?? 0.05);\n\n const parts: string[] = [];\n\n if (includeXml) parts.push('<?xml version=\"1.0\" encoding=\"UTF-8\"?>');\n\n const [minX, minY, width, height] = viewBox;\n parts.push(\n `<svg xmlns=\"http://www.w3.org/2000/svg\" ` +\n `viewBox=\"${minX} ${minY} ${width} ${height}\" ` +\n `width=\"${width}\" height=\"${height}\">`\n );\n\n if (options.backgroundColor) {\n parts.push(\n `<rect x=\"${minX}\" y=\"${minY}\" width=\"${width}\" height=\"${height}\" fill=\"${options.backgroundColor}\"/>`\n );\n }\n\n parts.push('<g fill=\"none\" stroke-linecap=\"round\" stroke-linejoin=\"round\">');\n\n const categories: Array<[keyof typeof proj, keyof Required<SvgRenderStyles>]> = [\n ['hiddenLines', 'hiddenLines'],\n ['outlineHidden', 'outlineHidden'],\n ['visibleLines', 'visibleLines'],\n ['outlineVisible', 'outlineVisible'],\n ['silhouettes', 'silhouettes'],\n ['featureEdges', 'featureEdges'],\n ['cutLines', 'cutLines'],\n ['stairArrows', 'stairArrows']\n ];\n\n for (const [key, styleKey] of categories) {\n const style = styles[styleKey];\n if (style.enabled) renderProjectedCategory(parts, proj[key], style, bounds);\n }\n\n parts.push('</g>');\n parts.push('</svg>');\n return parts.join('\\n');\n}\n\nfunction projectPolylines(polylines: Vec3[][], planeBasis?: SvgPlaneBasis): Pt2[][] {\n const result: Pt2[][] = [];\n for (const polyline of polylines) {\n if (polyline.length === 0) continue;\n const projected: Pt2[] = [];\n for (const point of polyline) {\n if (!Number.isFinite(point[0]) || !Number.isFinite(point[1]) || !Number.isFinite(point[2])) continue;\n if (planeBasis) {\n const dx = point[0] - planeBasis.origin.x;\n const dy = point[1] - planeBasis.origin.y;\n const dz = point[2] - planeBasis.origin.z;\n projected.push({\n x: dx * planeBasis.right.x + dy * planeBasis.right.y + dz * planeBasis.right.z,\n y: dx * planeBasis.up.x + dy * planeBasis.up.y + dz * planeBasis.up.z\n });\n } else {\n projected.push({ x: point[0], y: -point[2] });\n }\n }\n if (projected.length > 0) result.push(projected);\n }\n return result;\n}\n\nfunction computeBoundsFromProjected(categories: Record<string, Pt2[][]>): Bounds {\n let minX = Infinity,\n minY = Infinity,\n maxX = -Infinity,\n maxY = -Infinity;\n for (const polylines of Object.values(categories)) {\n for (const polyline of polylines) {\n for (const pt of polyline) {\n if (pt.x < minX) minX = pt.x;\n if (pt.x > maxX) maxX = pt.x;\n if (pt.y < minY) minY = pt.y;\n if (pt.y > maxY) maxY = pt.y;\n }\n }\n }\n if (!Number.isFinite(minX)) return { minX: 0, maxX: 1, minY: 0, maxY: 1 };\n return { minX, maxX, minY, maxY };\n}\n\nfunction renderProjectedCategory(\n parts: string[],\n polylines: Pt2[][],\n style: { stroke?: string; strokeWidth?: number; strokeDasharray?: string; opacity?: number },\n bounds: Bounds\n): void {\n if (!polylines.length) return;\n const pathData = projectedToPathData(polylines, bounds);\n if (!pathData) return;\n\n let pathElement = `<path d=\"${pathData}\"`;\n if (style.stroke) pathElement += ` stroke=\"${style.stroke}\"`;\n if (style.strokeWidth !== undefined) pathElement += ` stroke-width=\"${style.strokeWidth}\"`;\n if (style.strokeDasharray) pathElement += ` stroke-dasharray=\"${style.strokeDasharray}\"`;\n if (style.opacity !== undefined && style.opacity !== 1) pathElement += ` opacity=\"${style.opacity}\"`;\n pathElement += '/>';\n parts.push(pathElement);\n}\n\nfunction projectedToPathData(polylines: Pt2[][], bounds: Bounds): string {\n const parts: string[] = [];\n const ox = bounds.minX;\n const oy = bounds.maxY;\n for (const polyline of polylines) {\n if (polyline.length === 0) continue;\n parts.push(`M ${(polyline[0].x - ox).toFixed(6)} ${(oy - polyline[0].y).toFixed(6)}`);\n for (let i = 1; i < polyline.length; i++) {\n parts.push(`L ${(polyline[i].x - ox).toFixed(6)} ${(oy - polyline[i].y).toFixed(6)}`);\n }\n }\n return parts.join(' ');\n}\n\nfunction boundsToViewBox(bounds: Bounds, padding: number): [number, number, number, number] {\n const width = bounds.maxX - bounds.minX;\n const height = bounds.maxY - bounds.minY;\n const padAmount = Math.max(width, height) * padding;\n return [-padAmount, -padAmount, width + padAmount * 2, height + padAmount * 2];\n}\n\nfunction mergeStyles(userStyles?: SvgRenderStyles): Required<SvgRenderStyles> {\n return {\n cutLines: { ...DEFAULT_SVG_STYLES.cutLines, ...userStyles?.cutLines },\n visibleLines: { ...DEFAULT_SVG_STYLES.visibleLines, ...userStyles?.visibleLines },\n hiddenLines: { ...DEFAULT_SVG_STYLES.hiddenLines, ...userStyles?.hiddenLines },\n silhouettes: { ...DEFAULT_SVG_STYLES.silhouettes, ...userStyles?.silhouettes },\n featureEdges: { ...DEFAULT_SVG_STYLES.featureEdges, ...userStyles?.featureEdges },\n stairArrows: { ...DEFAULT_SVG_STYLES.stairArrows, ...userStyles?.stairArrows },\n outlineVisible: { ...DEFAULT_SVG_STYLES.outlineVisible, ...userStyles?.outlineVisible },\n outlineHidden: { ...DEFAULT_SVG_STYLES.outlineHidden, ...userStyles?.outlineHidden }\n };\n}\n"]}
|