@twinfinity/printing 5.0.3-ci.28538-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.
Files changed (209) hide show
  1. package/README.md +208 -0
  2. package/dist/BuildInfo.d.ts +25 -0
  3. package/dist/BuildInfo.d.ts.map +1 -0
  4. package/dist/BuildInfo.js +15 -0
  5. package/dist/BuildInfo.js.map +1 -0
  6. package/dist/index.d.ts +7 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +9 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/layout/analyzeTemplate.d.ts +29 -0
  11. package/dist/layout/analyzeTemplate.d.ts.map +1 -0
  12. package/dist/layout/analyzeTemplate.js +168 -0
  13. package/dist/layout/analyzeTemplate.js.map +1 -0
  14. package/dist/layout/clipUtils.d.ts +18 -0
  15. package/dist/layout/clipUtils.d.ts.map +1 -0
  16. package/dist/layout/clipUtils.js +165 -0
  17. package/dist/layout/clipUtils.js.map +1 -0
  18. package/dist/layout/colorConstants.d.ts +11 -0
  19. package/dist/layout/colorConstants.d.ts.map +1 -0
  20. package/dist/layout/colorConstants.js +14 -0
  21. package/dist/layout/colorConstants.js.map +1 -0
  22. package/dist/layout/elementKinds.d.ts +21 -0
  23. package/dist/layout/elementKinds.d.ts.map +1 -0
  24. package/dist/layout/elementKinds.js +17 -0
  25. package/dist/layout/elementKinds.js.map +1 -0
  26. package/dist/layout/exportDrawing.d.ts +143 -0
  27. package/dist/layout/exportDrawing.d.ts.map +1 -0
  28. package/dist/layout/exportDrawing.js +146 -0
  29. package/dist/layout/exportDrawing.js.map +1 -0
  30. package/dist/layout/filters.d.ts +33 -0
  31. package/dist/layout/filters.d.ts.map +1 -0
  32. package/dist/layout/filters.js +77 -0
  33. package/dist/layout/filters.js.map +1 -0
  34. package/dist/layout/geometryConstants.d.ts +8 -0
  35. package/dist/layout/geometryConstants.d.ts.map +1 -0
  36. package/dist/layout/geometryConstants.js +10 -0
  37. package/dist/layout/geometryConstants.js.map +1 -0
  38. package/dist/layout/index.d.ts +86 -0
  39. package/dist/layout/index.d.ts.map +1 -0
  40. package/dist/layout/index.js +363 -0
  41. package/dist/layout/index.js.map +1 -0
  42. package/dist/layout/itemBuilders.d.ts +29 -0
  43. package/dist/layout/itemBuilders.d.ts.map +1 -0
  44. package/dist/layout/itemBuilders.js +135 -0
  45. package/dist/layout/itemBuilders.js.map +1 -0
  46. package/dist/layout/labelsRender.d.ts +29 -0
  47. package/dist/layout/labelsRender.d.ts.map +1 -0
  48. package/dist/layout/labelsRender.js +109 -0
  49. package/dist/layout/labelsRender.js.map +1 -0
  50. package/dist/layout/legendConstants.d.ts +12 -0
  51. package/dist/layout/legendConstants.d.ts.map +1 -0
  52. package/dist/layout/legendConstants.js +12 -0
  53. package/dist/layout/legendConstants.js.map +1 -0
  54. package/dist/layout/legendRender.d.ts +13 -0
  55. package/dist/layout/legendRender.d.ts.map +1 -0
  56. package/dist/layout/legendRender.js +424 -0
  57. package/dist/layout/legendRender.js.map +1 -0
  58. package/dist/layout/legendRows.d.ts +26 -0
  59. package/dist/layout/legendRows.d.ts.map +1 -0
  60. package/dist/layout/legendRows.js +45 -0
  61. package/dist/layout/legendRows.js.map +1 -0
  62. package/dist/layout/legendUtils.d.ts +21 -0
  63. package/dist/layout/legendUtils.d.ts.map +1 -0
  64. package/dist/layout/legendUtils.js +110 -0
  65. package/dist/layout/legendUtils.js.map +1 -0
  66. package/dist/layout/metadata.d.ts +43 -0
  67. package/dist/layout/metadata.d.ts.map +1 -0
  68. package/dist/layout/metadata.js +191 -0
  69. package/dist/layout/metadata.js.map +1 -0
  70. package/dist/layout/model.d.ts +15 -0
  71. package/dist/layout/model.d.ts.map +1 -0
  72. package/dist/layout/model.js +310 -0
  73. package/dist/layout/model.js.map +1 -0
  74. package/dist/layout/options.d.ts +17 -0
  75. package/dist/layout/options.d.ts.map +1 -0
  76. package/dist/layout/options.js +2 -0
  77. package/dist/layout/options.js.map +1 -0
  78. package/dist/layout/presets.d.ts +23 -0
  79. package/dist/layout/presets.d.ts.map +1 -0
  80. package/dist/layout/presets.js +41 -0
  81. package/dist/layout/presets.js.map +1 -0
  82. package/dist/layout/qrRender.d.ts +13 -0
  83. package/dist/layout/qrRender.d.ts.map +1 -0
  84. package/dist/layout/qrRender.js +97 -0
  85. package/dist/layout/qrRender.js.map +1 -0
  86. package/dist/layout/renderDrawing.d.ts +62 -0
  87. package/dist/layout/renderDrawing.d.ts.map +1 -0
  88. package/dist/layout/renderDrawing.js +555 -0
  89. package/dist/layout/renderDrawing.js.map +1 -0
  90. package/dist/layout/renderUtils.d.ts +36 -0
  91. package/dist/layout/renderUtils.d.ts.map +1 -0
  92. package/dist/layout/renderUtils.js +117 -0
  93. package/dist/layout/renderUtils.js.map +1 -0
  94. package/dist/layout/sectionValidation.d.ts +3 -0
  95. package/dist/layout/sectionValidation.d.ts.map +1 -0
  96. package/dist/layout/sectionValidation.js +2 -0
  97. package/dist/layout/sectionValidation.js.map +1 -0
  98. package/dist/layout/templateVariables.d.ts +137 -0
  99. package/dist/layout/templateVariables.d.ts.map +1 -0
  100. package/dist/layout/templateVariables.js +295 -0
  101. package/dist/layout/templateVariables.js.map +1 -0
  102. package/dist/layout/typeGuards.d.ts +5 -0
  103. package/dist/layout/typeGuards.d.ts.map +1 -0
  104. package/dist/layout/typeGuards.js +9 -0
  105. package/dist/layout/typeGuards.js.map +1 -0
  106. package/dist/layout/types.d.ts +816 -0
  107. package/dist/layout/types.d.ts.map +1 -0
  108. package/dist/layout/types.js +2 -0
  109. package/dist/layout/types.js.map +1 -0
  110. package/dist/layout/utils.d.ts +9 -0
  111. package/dist/layout/utils.d.ts.map +1 -0
  112. package/dist/layout/utils.js +84 -0
  113. package/dist/layout/utils.js.map +1 -0
  114. package/dist/layout/validation.d.ts +7 -0
  115. package/dist/layout/validation.d.ts.map +1 -0
  116. package/dist/layout/validation.js +352 -0
  117. package/dist/layout/validation.js.map +1 -0
  118. package/dist/layout/validationHelpers.d.ts +15 -0
  119. package/dist/layout/validationHelpers.d.ts.map +1 -0
  120. package/dist/layout/validationHelpers.js +43 -0
  121. package/dist/layout/validationHelpers.js.map +1 -0
  122. package/dist/layout/validationUtils.d.ts +5 -0
  123. package/dist/layout/validationUtils.d.ts.map +1 -0
  124. package/dist/layout/validationUtils.js +5 -0
  125. package/dist/layout/validationUtils.js.map +1 -0
  126. package/dist/layout/viewportPrep.d.ts +47 -0
  127. package/dist/layout/viewportPrep.d.ts.map +1 -0
  128. package/dist/layout/viewportPrep.js +275 -0
  129. package/dist/layout/viewportPrep.js.map +1 -0
  130. package/dist/layout/viewportRender.d.ts +42 -0
  131. package/dist/layout/viewportRender.d.ts.map +1 -0
  132. package/dist/layout/viewportRender.js +337 -0
  133. package/dist/layout/viewportRender.js.map +1 -0
  134. package/dist/layout/viewportUtils.d.ts +9 -0
  135. package/dist/layout/viewportUtils.d.ts.map +1 -0
  136. package/dist/layout/viewportUtils.js +40 -0
  137. package/dist/layout/viewportUtils.js.map +1 -0
  138. package/dist/layout/warnings.d.ts +2 -0
  139. package/dist/layout/warnings.d.ts.map +1 -0
  140. package/dist/layout/warnings.js +4 -0
  141. package/dist/layout/warnings.js.map +1 -0
  142. package/dist/printToPdf.d.ts +38 -0
  143. package/dist/printToPdf.d.ts.map +1 -0
  144. package/dist/printToPdf.js +79 -0
  145. package/dist/printToPdf.js.map +1 -0
  146. package/dist/printToSvg.d.ts +11 -0
  147. package/dist/printToSvg.d.ts.map +1 -0
  148. package/dist/printToSvg.js +168 -0
  149. package/dist/printToSvg.js.map +1 -0
  150. package/dist/sections.d.ts +118 -0
  151. package/dist/sections.d.ts.map +1 -0
  152. package/dist/sections.js +839 -0
  153. package/dist/sections.js.map +1 -0
  154. package/dist/templates/default-template.json +137 -0
  155. package/dist/types.d.ts +54 -0
  156. package/dist/types.d.ts.map +1 -0
  157. package/dist/types.js +11 -0
  158. package/dist/types.js.map +1 -0
  159. package/package.json +47 -0
  160. package/src/BuildInfo.ts +41 -0
  161. package/src/index.ts +10 -0
  162. package/src/layout/analyzeTemplate.ts +218 -0
  163. package/src/layout/clipUtils.ts +193 -0
  164. package/src/layout/colorConstants.ts +16 -0
  165. package/src/layout/elementKinds.ts +35 -0
  166. package/src/layout/exportDrawing.ts +206 -0
  167. package/src/layout/filters.ts +80 -0
  168. package/src/layout/geometryConstants.ts +11 -0
  169. package/src/layout/index.ts +671 -0
  170. package/src/layout/itemBuilders.ts +159 -0
  171. package/src/layout/labelsRender.ts +170 -0
  172. package/src/layout/legendConstants.ts +11 -0
  173. package/src/layout/legendRender.ts +543 -0
  174. package/src/layout/legendRows.ts +62 -0
  175. package/src/layout/legendUtils.ts +144 -0
  176. package/src/layout/metadata.ts +210 -0
  177. package/src/layout/model.ts +372 -0
  178. package/src/layout/options.ts +17 -0
  179. package/src/layout/presets.ts +51 -0
  180. package/src/layout/qrRender.ts +126 -0
  181. package/src/layout/qrcode.d.ts +2 -0
  182. package/src/layout/renderDrawing.ts +710 -0
  183. package/src/layout/renderUtils.ts +138 -0
  184. package/src/layout/sectionValidation.ts +2 -0
  185. package/src/layout/templateVariables.ts +317 -0
  186. package/src/layout/typeGuards.ts +9 -0
  187. package/src/layout/types.ts +835 -0
  188. package/src/layout/utils.ts +85 -0
  189. package/src/layout/validation.ts +392 -0
  190. package/src/layout/validationHelpers.ts +59 -0
  191. package/src/layout/validationUtils.ts +6 -0
  192. package/src/layout/viewportPrep.ts +351 -0
  193. package/src/layout/viewportRender.ts +442 -0
  194. package/src/layout/viewportUtils.ts +50 -0
  195. package/src/layout/warnings.ts +3 -0
  196. package/src/printToPdf.ts +108 -0
  197. package/src/printToSvg.ts +188 -0
  198. package/src/sections.ts +1019 -0
  199. package/src/templates/default-template.json +137 -0
  200. package/src/types.ts +49 -0
  201. package/templates/default-a0-landscape.json +209 -0
  202. package/templates/default-a0-portrait.json +195 -0
  203. package/templates/default-a1-landscape.json +167 -0
  204. package/templates/default-a1-portrait.json +153 -0
  205. package/templates/default-a3-landscape.json +111 -0
  206. package/templates/default-a3-portrait.json +125 -0
  207. package/templates/default-a4-landscape.json +97 -0
  208. package/templates/default-a4-portrait.json +97 -0
  209. package/templates/template-schema.json +1395 -0
@@ -0,0 +1,188 @@
1
+ import type { SlabSectionGeometry, Vec3 } from '@twinfinity/geometry';
2
+ import type { PrintToSvgOptions, SvgRenderStyles, SvgPlaneBasis } from './types';
3
+ import { DEFAULT_SVG_STYLES } from './types';
4
+
5
+ type Pt2 = { x: number; y: number };
6
+ type Bounds = { minX: number; maxX: number; minY: number; maxY: number };
7
+
8
+ /**
9
+ * Render SlabSectionGeometry to an SVG string.
10
+ *
11
+ * @param geometry The computed slab section geometry
12
+ * @param options Rendering options (viewBox, styles, planeBasis, etc.)
13
+ * @returns Complete SVG string
14
+ */
15
+ export function printToSvg(geometry: SlabSectionGeometry, options: PrintToSvgOptions = {}): string {
16
+ if (!geometry) throw new Error('geometry is required');
17
+
18
+ if (
19
+ options.boundsPadding !== undefined &&
20
+ (typeof options.boundsPadding !== 'number' || options.boundsPadding < 0)
21
+ ) {
22
+ throw new Error('boundsPadding must be a non-negative number');
23
+ }
24
+
25
+ if (options.viewBox) {
26
+ if (!Array.isArray(options.viewBox) || options.viewBox.length !== 4) {
27
+ throw new Error('viewBox must be an array of 4 numbers [minX, minY, width, height]');
28
+ }
29
+ for (let i = 0; i < 4; i++) {
30
+ if (typeof options.viewBox[i] !== 'number' || !Number.isFinite(options.viewBox[i])) {
31
+ throw new Error(`viewBox[${i}] must be a finite number`);
32
+ }
33
+ }
34
+ }
35
+
36
+ const styles = mergeStyles(options.styles);
37
+ const includeXml = options.includeXmlDeclaration ?? true;
38
+
39
+ // Project all polylines to 2D once
40
+ const proj = {
41
+ hiddenLines: projectPolylines(geometry.hiddenLines, options.planeBasis),
42
+ outlineHidden: projectPolylines(geometry.outlineHidden, options.planeBasis),
43
+ visibleLines: projectPolylines(geometry.visibleLines, options.planeBasis),
44
+ outlineVisible: projectPolylines(geometry.outlineVisible, options.planeBasis),
45
+ silhouettes: projectPolylines(geometry.silhouettes, options.planeBasis),
46
+ featureEdges: projectPolylines(geometry.featureEdges, options.planeBasis),
47
+ cutLines: projectPolylines(geometry.cutLines, options.planeBasis),
48
+ stairArrows: projectPolylines(geometry.stairArrows, options.planeBasis)
49
+ };
50
+
51
+ const bounds = options.bounds ?? computeBoundsFromProjected(proj);
52
+ const viewBox = options.viewBox ?? boundsToViewBox(bounds, options.boundsPadding ?? 0.05);
53
+
54
+ const parts: string[] = [];
55
+
56
+ if (includeXml) parts.push('<?xml version="1.0" encoding="UTF-8"?>');
57
+
58
+ const [minX, minY, width, height] = viewBox;
59
+ parts.push(
60
+ `<svg xmlns="http://www.w3.org/2000/svg" ` +
61
+ `viewBox="${minX} ${minY} ${width} ${height}" ` +
62
+ `width="${width}" height="${height}">`
63
+ );
64
+
65
+ if (options.backgroundColor) {
66
+ parts.push(
67
+ `<rect x="${minX}" y="${minY}" width="${width}" height="${height}" fill="${options.backgroundColor}"/>`
68
+ );
69
+ }
70
+
71
+ parts.push('<g fill="none" stroke-linecap="round" stroke-linejoin="round">');
72
+
73
+ const categories: Array<[keyof typeof proj, keyof Required<SvgRenderStyles>]> = [
74
+ ['hiddenLines', 'hiddenLines'],
75
+ ['outlineHidden', 'outlineHidden'],
76
+ ['visibleLines', 'visibleLines'],
77
+ ['outlineVisible', 'outlineVisible'],
78
+ ['silhouettes', 'silhouettes'],
79
+ ['featureEdges', 'featureEdges'],
80
+ ['cutLines', 'cutLines'],
81
+ ['stairArrows', 'stairArrows']
82
+ ];
83
+
84
+ for (const [key, styleKey] of categories) {
85
+ const style = styles[styleKey];
86
+ if (style.enabled) renderProjectedCategory(parts, proj[key], style, bounds);
87
+ }
88
+
89
+ parts.push('</g>');
90
+ parts.push('</svg>');
91
+ return parts.join('\n');
92
+ }
93
+
94
+ function projectPolylines(polylines: Vec3[][], planeBasis?: SvgPlaneBasis): Pt2[][] {
95
+ const result: Pt2[][] = [];
96
+ for (const polyline of polylines) {
97
+ if (polyline.length === 0) continue;
98
+ const projected: Pt2[] = [];
99
+ for (const point of polyline) {
100
+ if (!Number.isFinite(point[0]) || !Number.isFinite(point[1]) || !Number.isFinite(point[2])) continue;
101
+ if (planeBasis) {
102
+ const dx = point[0] - planeBasis.origin.x;
103
+ const dy = point[1] - planeBasis.origin.y;
104
+ const dz = point[2] - planeBasis.origin.z;
105
+ projected.push({
106
+ x: dx * planeBasis.right.x + dy * planeBasis.right.y + dz * planeBasis.right.z,
107
+ y: dx * planeBasis.up.x + dy * planeBasis.up.y + dz * planeBasis.up.z
108
+ });
109
+ } else {
110
+ projected.push({ x: point[0], y: -point[2] });
111
+ }
112
+ }
113
+ if (projected.length > 0) result.push(projected);
114
+ }
115
+ return result;
116
+ }
117
+
118
+ function computeBoundsFromProjected(categories: Record<string, Pt2[][]>): Bounds {
119
+ let minX = Infinity,
120
+ minY = Infinity,
121
+ maxX = -Infinity,
122
+ maxY = -Infinity;
123
+ for (const polylines of Object.values(categories)) {
124
+ for (const polyline of polylines) {
125
+ for (const pt of polyline) {
126
+ if (pt.x < minX) minX = pt.x;
127
+ if (pt.x > maxX) maxX = pt.x;
128
+ if (pt.y < minY) minY = pt.y;
129
+ if (pt.y > maxY) maxY = pt.y;
130
+ }
131
+ }
132
+ }
133
+ if (!Number.isFinite(minX)) return { minX: 0, maxX: 1, minY: 0, maxY: 1 };
134
+ return { minX, maxX, minY, maxY };
135
+ }
136
+
137
+ function renderProjectedCategory(
138
+ parts: string[],
139
+ polylines: Pt2[][],
140
+ style: { stroke?: string; strokeWidth?: number; strokeDasharray?: string; opacity?: number },
141
+ bounds: Bounds
142
+ ): void {
143
+ if (!polylines.length) return;
144
+ const pathData = projectedToPathData(polylines, bounds);
145
+ if (!pathData) return;
146
+
147
+ let pathElement = `<path d="${pathData}"`;
148
+ if (style.stroke) pathElement += ` stroke="${style.stroke}"`;
149
+ if (style.strokeWidth !== undefined) pathElement += ` stroke-width="${style.strokeWidth}"`;
150
+ if (style.strokeDasharray) pathElement += ` stroke-dasharray="${style.strokeDasharray}"`;
151
+ if (style.opacity !== undefined && style.opacity !== 1) pathElement += ` opacity="${style.opacity}"`;
152
+ pathElement += '/>';
153
+ parts.push(pathElement);
154
+ }
155
+
156
+ function projectedToPathData(polylines: Pt2[][], bounds: Bounds): string {
157
+ const parts: string[] = [];
158
+ const ox = bounds.minX;
159
+ const oy = bounds.maxY;
160
+ for (const polyline of polylines) {
161
+ if (polyline.length === 0) continue;
162
+ parts.push(`M ${(polyline[0].x - ox).toFixed(6)} ${(oy - polyline[0].y).toFixed(6)}`);
163
+ for (let i = 1; i < polyline.length; i++) {
164
+ parts.push(`L ${(polyline[i].x - ox).toFixed(6)} ${(oy - polyline[i].y).toFixed(6)}`);
165
+ }
166
+ }
167
+ return parts.join(' ');
168
+ }
169
+
170
+ function boundsToViewBox(bounds: Bounds, padding: number): [number, number, number, number] {
171
+ const width = bounds.maxX - bounds.minX;
172
+ const height = bounds.maxY - bounds.minY;
173
+ const padAmount = Math.max(width, height) * padding;
174
+ return [-padAmount, -padAmount, width + padAmount * 2, height + padAmount * 2];
175
+ }
176
+
177
+ function mergeStyles(userStyles?: SvgRenderStyles): Required<SvgRenderStyles> {
178
+ return {
179
+ cutLines: { ...DEFAULT_SVG_STYLES.cutLines, ...userStyles?.cutLines },
180
+ visibleLines: { ...DEFAULT_SVG_STYLES.visibleLines, ...userStyles?.visibleLines },
181
+ hiddenLines: { ...DEFAULT_SVG_STYLES.hiddenLines, ...userStyles?.hiddenLines },
182
+ silhouettes: { ...DEFAULT_SVG_STYLES.silhouettes, ...userStyles?.silhouettes },
183
+ featureEdges: { ...DEFAULT_SVG_STYLES.featureEdges, ...userStyles?.featureEdges },
184
+ stairArrows: { ...DEFAULT_SVG_STYLES.stairArrows, ...userStyles?.stairArrows },
185
+ outlineVisible: { ...DEFAULT_SVG_STYLES.outlineVisible, ...userStyles?.outlineVisible },
186
+ outlineHidden: { ...DEFAULT_SVG_STYLES.outlineHidden, ...userStyles?.outlineHidden }
187
+ };
188
+ }