@twinfinity/printing 6.1.0-beta → 6.1.2-ci.30738-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/dist/BuildInfo.js +3 -3
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/layout/analyzeTemplate.d.ts +4 -4
- package/dist/layout/analyzeTemplate.d.ts.map +1 -1
- package/dist/layout/analyzeTemplate.js +18 -16
- package/dist/layout/analyzeTemplate.js.map +1 -1
- package/dist/layout/classClosure.d.ts +41 -0
- package/dist/layout/classClosure.d.ts.map +1 -0
- package/dist/layout/classClosure.js +143 -0
- package/dist/layout/classClosure.js.map +1 -0
- package/dist/layout/clipUtils.d.ts +11 -0
- package/dist/layout/clipUtils.d.ts.map +1 -1
- package/dist/layout/clipUtils.js +67 -6
- package/dist/layout/clipUtils.js.map +1 -1
- package/dist/layout/filters.d.ts +14 -8
- package/dist/layout/filters.d.ts.map +1 -1
- package/dist/layout/filters.js +28 -3
- package/dist/layout/filters.js.map +1 -1
- package/dist/layout/index.d.ts +24 -57
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +20 -337
- package/dist/layout/index.js.map +1 -1
- package/dist/layout/itemBuilders.d.ts +11 -0
- package/dist/layout/itemBuilders.d.ts.map +1 -1
- package/dist/layout/itemBuilders.js +17 -3
- package/dist/layout/itemBuilders.js.map +1 -1
- package/dist/layout/labelsRender.d.ts.map +1 -1
- package/dist/layout/labelsRender.js +15 -27
- package/dist/layout/labelsRender.js.map +1 -1
- package/dist/layout/legendRender.d.ts +18 -6
- package/dist/layout/legendRender.d.ts.map +1 -1
- package/dist/layout/legendRender.js +49 -79
- package/dist/layout/legendRender.js.map +1 -1
- package/dist/layout/metadata.d.ts.map +1 -1
- package/dist/layout/metadata.js +26 -5
- package/dist/layout/metadata.js.map +1 -1
- package/dist/layout/model.d.ts +4 -3
- package/dist/layout/model.d.ts.map +1 -1
- package/dist/layout/model.js +17 -57
- package/dist/layout/model.js.map +1 -1
- package/dist/layout/options.d.ts +1 -2
- package/dist/layout/options.d.ts.map +1 -1
- package/dist/layout/options.js.map +1 -1
- package/dist/layout/preflight.d.ts +32 -0
- package/dist/layout/preflight.d.ts.map +1 -0
- package/dist/layout/preflight.js +69 -0
- package/dist/layout/preflight.js.map +1 -0
- package/dist/layout/qrRender.d.ts.map +1 -1
- package/dist/layout/qrRender.js +11 -10
- package/dist/layout/qrRender.js.map +1 -1
- package/dist/layout/renderDrawing.d.ts +28 -17
- package/dist/layout/renderDrawing.d.ts.map +1 -1
- package/dist/layout/renderDrawing.js +107 -88
- package/dist/layout/renderDrawing.js.map +1 -1
- package/dist/layout/renderLayout.d.ts +25 -0
- package/dist/layout/renderLayout.d.ts.map +1 -0
- package/dist/layout/renderLayout.js +315 -0
- package/dist/layout/renderLayout.js.map +1 -0
- package/dist/layout/renderTemplateSheet.d.ts +99 -0
- package/dist/layout/renderTemplateSheet.d.ts.map +1 -0
- package/dist/layout/renderTemplateSheet.js +296 -0
- package/dist/layout/renderTemplateSheet.js.map +1 -0
- package/dist/layout/renderUtils.d.ts +19 -0
- package/dist/layout/renderUtils.d.ts.map +1 -1
- package/dist/layout/renderUtils.js +47 -4
- package/dist/layout/renderUtils.js.map +1 -1
- package/dist/layout/sectionDefs.d.ts +65 -0
- package/dist/layout/sectionDefs.d.ts.map +1 -0
- package/dist/layout/sectionDefs.js +88 -0
- package/dist/layout/sectionDefs.js.map +1 -0
- package/dist/layout/slabModelView.d.ts +34 -0
- package/dist/layout/slabModelView.d.ts.map +1 -0
- package/dist/layout/slabModelView.js +175 -0
- package/dist/layout/slabModelView.js.map +1 -0
- package/dist/layout/templateVariables.d.ts +1 -1
- package/dist/layout/templateVariables.d.ts.map +1 -1
- package/dist/layout/templateVariables.js +21 -9
- package/dist/layout/templateVariables.js.map +1 -1
- package/dist/layout/types.d.ts +164 -83
- package/dist/layout/types.d.ts.map +1 -1
- package/dist/layout/types.js.map +1 -1
- package/dist/layout/validation.d.ts.map +1 -1
- package/dist/layout/validation.js +78 -33
- package/dist/layout/validation.js.map +1 -1
- package/dist/layout/viewportPrep.d.ts +8 -6
- package/dist/layout/viewportPrep.d.ts.map +1 -1
- package/dist/layout/viewportPrep.js +35 -23
- package/dist/layout/viewportPrep.js.map +1 -1
- package/dist/layout/viewportRender.d.ts +9 -7
- package/dist/layout/viewportRender.d.ts.map +1 -1
- package/dist/layout/viewportRender.js +93 -126
- package/dist/layout/viewportRender.js.map +1 -1
- package/dist/layout/viewportUtils.d.ts +20 -0
- package/dist/layout/viewportUtils.d.ts.map +1 -1
- package/dist/layout/viewportUtils.js +107 -4
- package/dist/layout/viewportUtils.js.map +1 -1
- package/dist/printToPdf.d.ts +7 -1
- package/dist/printToPdf.d.ts.map +1 -1
- package/dist/printToPdf.js +81 -14
- package/dist/printToPdf.js.map +1 -1
- package/dist/printToSvg.d.ts.map +1 -1
- package/dist/printToSvg.js +7 -3
- package/dist/printToSvg.js.map +1 -1
- package/dist/schemaUtils.d.ts +9 -0
- package/dist/schemaUtils.d.ts.map +1 -0
- package/dist/schemaUtils.js +14 -0
- package/dist/schemaUtils.js.map +1 -0
- package/dist/templates/default-template.json +30 -8
- package/dist/types.d.ts +2 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +10 -1
- package/dist/types.js.map +1 -1
- package/package.json +8 -3
- package/src/index.ts +4 -0
- package/src/layout/analyzeTemplate.ts +21 -19
- package/src/layout/classClosure.ts +142 -0
- package/src/layout/clipUtils.ts +65 -6
- package/src/layout/filters.ts +31 -3
- package/src/layout/index.ts +61 -571
- package/src/layout/itemBuilders.ts +20 -5
- package/src/layout/labelsRender.ts +23 -40
- package/src/layout/legendRender.ts +64 -84
- package/src/layout/metadata.ts +26 -5
- package/src/layout/model.ts +21 -66
- package/src/layout/options.ts +1 -2
- package/src/layout/preflight.ts +96 -0
- package/src/layout/qrRender.ts +11 -10
- package/src/layout/renderDrawing.ts +132 -110
- package/src/layout/renderLayout.ts +483 -0
- package/src/layout/renderTemplateSheet.ts +435 -0
- package/src/layout/renderUtils.ts +53 -4
- package/src/layout/sectionDefs.ts +131 -0
- package/src/layout/slabModelView.ts +196 -0
- package/src/layout/templateVariables.ts +25 -9
- package/src/layout/types.ts +160 -70
- package/src/layout/validation.ts +98 -32
- package/src/layout/viewportPrep.ts +47 -29
- package/src/layout/viewportRender.ts +114 -141
- package/src/layout/viewportUtils.ts +118 -5
- package/src/printToPdf.ts +84 -15
- package/src/printToSvg.ts +7 -3
- package/src/schemaUtils.ts +13 -0
- package/src/templates/default-template.json +30 -8
- package/src/types.ts +12 -2
- package/templates/default-a0-landscape.json +171 -66
- package/templates/default-a0-portrait.json +159 -60
- package/templates/default-a1-landscape.json +135 -48
- package/templates/default-a1-portrait.json +123 -42
- package/templates/default-a3-landscape.json +87 -24
- package/templates/default-a3-portrait.json +99 -30
- package/templates/default-a4-landscape.json +75 -18
- package/templates/default-a4-portrait.json +75 -18
- package/templates/llm-authoring-guide.md +247 -0
- package/templates/template-schema.json +295 -120
package/src/printToPdf.ts
CHANGED
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
export interface PrintToPdfOptions {
|
|
8
8
|
svgMarkup: string;
|
|
9
9
|
fileName?: string;
|
|
10
|
-
|
|
10
|
+
/** ISO name or an arbitrary [width, height] in mm. */
|
|
11
|
+
pageFormat?: 'a0' | 'a1' | 'a2' | 'a3' | 'a4' | [number, number];
|
|
11
12
|
orientation?: 'portrait' | 'landscape';
|
|
12
13
|
marginMm?: number;
|
|
13
14
|
}
|
|
@@ -17,16 +18,16 @@ export interface PrintToPdfOptions {
|
|
|
17
18
|
* Requires jspdf and svg2pdf.js as peer dependencies.
|
|
18
19
|
*/
|
|
19
20
|
export async function printToPdf(options: PrintToPdfOptions): Promise<Blob> {
|
|
20
|
-
// Dynamic imports for optional peer dependencies (installed by consumer,
|
|
21
|
+
// Dynamic imports for optional peer dependencies (installed by consumer,
|
|
22
|
+
// not this package). Typechecked against the workspace-hoisted installs
|
|
23
|
+
// (template-workbench depends on both), resolved at runtime for consumers.
|
|
21
24
|
let jspdfModule: any;
|
|
22
25
|
try {
|
|
23
|
-
// @ts-expect-error — optional peer dependency resolved at runtime
|
|
24
26
|
jspdfModule = await import('jspdf');
|
|
25
27
|
} catch {
|
|
26
28
|
throw new Error('jspdf is required for PDF export. Install it: bun add jspdf');
|
|
27
29
|
}
|
|
28
30
|
try {
|
|
29
|
-
// @ts-expect-error — optional peer dependency resolved at runtime
|
|
30
31
|
await import('svg2pdf.js');
|
|
31
32
|
} catch {
|
|
32
33
|
throw new Error('svg2pdf.js is required for PDF export. Install it: bun add svg2pdf.js');
|
|
@@ -37,7 +38,10 @@ export async function printToPdf(options: PrintToPdfOptions): Promise<Blob> {
|
|
|
37
38
|
const orientation = options.orientation ?? 'landscape';
|
|
38
39
|
const margin = options.marginMm ?? 10;
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
// compress: jsPDF leaves content streams uncompressed by default — a full
|
|
42
|
+
// sheet of vector linework is megabytes of plain text. Flate matches what
|
|
43
|
+
// browser print-to-PDF produces (~5-10x smaller for typical sheets).
|
|
44
|
+
const doc = new jsPDF({ format, orientation, unit: 'mm', compress: true });
|
|
41
45
|
const pageWidth = doc.internal.pageSize.getWidth();
|
|
42
46
|
const pageHeight = doc.internal.pageSize.getHeight();
|
|
43
47
|
|
|
@@ -45,12 +49,29 @@ export async function printToPdf(options: PrintToPdfOptions): Promise<Blob> {
|
|
|
45
49
|
const svgDoc = parser.parseFromString(options.svgMarkup, 'image/svg+xml');
|
|
46
50
|
const svgElement = svgDoc.documentElement;
|
|
47
51
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
try {
|
|
53
|
+
await doc.svg(svgElement, {
|
|
54
|
+
x: margin,
|
|
55
|
+
y: margin,
|
|
56
|
+
width: pageWidth - margin * 2,
|
|
57
|
+
height: pageHeight - margin * 2
|
|
58
|
+
});
|
|
59
|
+
} catch (err) {
|
|
60
|
+
// svg2pdf loads every <image> href over XHR and rejects with the raw
|
|
61
|
+
// ProgressEvent on network/CORS failure — which stringifies to the
|
|
62
|
+
// useless "[object ProgressEvent]". Translate, and name the linked
|
|
63
|
+
// images so the failing one is findable. Remote images render fine in
|
|
64
|
+
// the browser preview but fail export unless the host sends CORS
|
|
65
|
+
// headers; data: URIs and inline resource `content` always work.
|
|
66
|
+
if (err instanceof Error) throw err;
|
|
67
|
+
const hrefs = collectImageHrefs(options.svgMarkup);
|
|
68
|
+
throw new Error(
|
|
69
|
+
'PDF export failed while loading a linked <image> resource (network or CORS). ' +
|
|
70
|
+
'Template images must be data: URIs, inline SVG resource `content`, or served ' +
|
|
71
|
+
'with CORS headers — the on-screen preview does not enforce this, PDF export does.' +
|
|
72
|
+
(hrefs.length ? ` Linked images: ${hrefs.join(', ')}` : '')
|
|
73
|
+
);
|
|
74
|
+
}
|
|
54
75
|
|
|
55
76
|
const blob = doc.output('blob');
|
|
56
77
|
|
|
@@ -61,6 +82,24 @@ export async function printToPdf(options: PrintToPdfOptions): Promise<Blob> {
|
|
|
61
82
|
return blob;
|
|
62
83
|
}
|
|
63
84
|
|
|
85
|
+
/**
|
|
86
|
+
* External image references in an SVG, for error reporting. data: URIs are
|
|
87
|
+
* summarized rather than dumped (they can be hundreds of KB).
|
|
88
|
+
*/
|
|
89
|
+
export function collectImageHrefs(svgMarkup: string): string[] {
|
|
90
|
+
const hrefs: string[] = [];
|
|
91
|
+
// Both quote styles: SVG allows either, and this feeds an error message — matching only double
|
|
92
|
+
// quotes meant the "which image broke the export?" hint could come back empty on valid markup,
|
|
93
|
+
// which is worse than not having it.
|
|
94
|
+
for (const m of svgMarkup.matchAll(/<image\b[^>]*?(?:xlink:)?href\s*=\s*("([^"]*)"|'([^']*)')/g)) {
|
|
95
|
+
const href = m[2] ?? m[3] ?? '';
|
|
96
|
+
hrefs.push(
|
|
97
|
+
href.startsWith('data:') ? `${href.slice(0, href.indexOf(',') + 1 || 32)}… (${href.length} chars)` : href
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return hrefs;
|
|
101
|
+
}
|
|
102
|
+
|
|
64
103
|
/**
|
|
65
104
|
* Export an SVG string directly as a downloadable SVG file.
|
|
66
105
|
*/
|
|
@@ -83,10 +122,40 @@ export interface ExportSectionToPdfOptions {
|
|
|
83
122
|
}
|
|
84
123
|
|
|
85
124
|
export async function exportSectionToPdf(options: ExportSectionToPdfOptions): Promise<void> {
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
125
|
+
const size = options.pageSizeMm;
|
|
126
|
+
// Claim the tab synchronously, while still inside the click that started this. Opening it after
|
|
127
|
+
// the await puts the call outside the user gesture, which is precisely what popup blockers stop
|
|
128
|
+
// — and rendering a sheet takes long enough that they always would.
|
|
129
|
+
const tab = options.openInNewTab ? window.open('', '_blank') : null;
|
|
130
|
+
let blob: Blob;
|
|
131
|
+
try {
|
|
132
|
+
blob = await printToPdf({
|
|
133
|
+
svgMarkup: options.svgMarkup,
|
|
134
|
+
// When opening in a tab, skip jsPDF's own save() download.
|
|
135
|
+
fileName: options.openInNewTab ? undefined : options.fileName,
|
|
136
|
+
pageFormat: size ? [size.width, size.height] : undefined,
|
|
137
|
+
orientation: size ? (size.width >= size.height ? 'landscape' : 'portrait') : undefined,
|
|
138
|
+
marginMm: size ? 0 : undefined
|
|
139
|
+
});
|
|
140
|
+
} catch (err) {
|
|
141
|
+
// Claiming the tab up front means a failed export would otherwise leave an empty one sitting
|
|
142
|
+
// there — and a broken linked <image> makes this throw, which is not a rare path.
|
|
143
|
+
tab?.close();
|
|
144
|
+
throw err;
|
|
145
|
+
}
|
|
146
|
+
if (options.openInNewTab) {
|
|
147
|
+
const url = URL.createObjectURL(blob);
|
|
148
|
+
// A blocked window.open returns null; fall back to the download so the export still lands
|
|
149
|
+
// somewhere the user can find rather than appearing to do nothing.
|
|
150
|
+
if (tab) tab.location.href = url;
|
|
151
|
+
else {
|
|
152
|
+
const link = document.createElement('a');
|
|
153
|
+
link.href = url;
|
|
154
|
+
link.download = options.fileName;
|
|
155
|
+
link.click();
|
|
156
|
+
}
|
|
157
|
+
setTimeout(() => URL.revokeObjectURL(url), 60_000);
|
|
158
|
+
}
|
|
90
159
|
}
|
|
91
160
|
|
|
92
161
|
export interface ExportSectionToSvgOptions {
|
package/src/printToSvg.ts
CHANGED
|
@@ -40,9 +40,10 @@ export function printToSvg(geometry: SlabSectionGeometry, options: PrintToSvgOpt
|
|
|
40
40
|
const proj = {
|
|
41
41
|
hiddenLines: projectPolylines(geometry.hiddenLines, options.planeBasis),
|
|
42
42
|
outlineHidden: projectPolylines(geometry.outlineHidden, options.planeBasis),
|
|
43
|
+
silhouettesHidden: projectPolylines(geometry.silhouettesHidden, options.planeBasis),
|
|
43
44
|
visibleLines: projectPolylines(geometry.visibleLines, options.planeBasis),
|
|
44
45
|
outlineVisible: projectPolylines(geometry.outlineVisible, options.planeBasis),
|
|
45
|
-
|
|
46
|
+
silhouettesVisible: projectPolylines(geometry.silhouettesVisible, options.planeBasis),
|
|
46
47
|
featureEdges: projectPolylines(geometry.featureEdges, options.planeBasis),
|
|
47
48
|
cutLines: projectPolylines(geometry.cutLines, options.planeBasis),
|
|
48
49
|
stairArrows: projectPolylines(geometry.stairArrows, options.planeBasis)
|
|
@@ -70,12 +71,14 @@ export function printToSvg(geometry: SlabSectionGeometry, options: PrintToSvgOpt
|
|
|
70
71
|
|
|
71
72
|
parts.push('<g fill="none" stroke-linecap="round" stroke-linejoin="round">');
|
|
72
73
|
|
|
74
|
+
// Hidden categories paint first so visible linework always draws over them.
|
|
73
75
|
const categories: Array<[keyof typeof proj, keyof Required<SvgRenderStyles>]> = [
|
|
74
76
|
['hiddenLines', 'hiddenLines'],
|
|
75
77
|
['outlineHidden', 'outlineHidden'],
|
|
78
|
+
['silhouettesHidden', 'silhouettesHidden'],
|
|
76
79
|
['visibleLines', 'visibleLines'],
|
|
77
80
|
['outlineVisible', 'outlineVisible'],
|
|
78
|
-
['
|
|
81
|
+
['silhouettesVisible', 'silhouettesVisible'],
|
|
79
82
|
['featureEdges', 'featureEdges'],
|
|
80
83
|
['cutLines', 'cutLines'],
|
|
81
84
|
['stairArrows', 'stairArrows']
|
|
@@ -179,7 +182,8 @@ function mergeStyles(userStyles?: SvgRenderStyles): Required<SvgRenderStyles> {
|
|
|
179
182
|
cutLines: { ...DEFAULT_SVG_STYLES.cutLines, ...userStyles?.cutLines },
|
|
180
183
|
visibleLines: { ...DEFAULT_SVG_STYLES.visibleLines, ...userStyles?.visibleLines },
|
|
181
184
|
hiddenLines: { ...DEFAULT_SVG_STYLES.hiddenLines, ...userStyles?.hiddenLines },
|
|
182
|
-
|
|
185
|
+
silhouettesVisible: { ...DEFAULT_SVG_STYLES.silhouettesVisible, ...userStyles?.silhouettesVisible },
|
|
186
|
+
silhouettesHidden: { ...DEFAULT_SVG_STYLES.silhouettesHidden, ...userStyles?.silhouettesHidden },
|
|
183
187
|
featureEdges: { ...DEFAULT_SVG_STYLES.featureEdges, ...userStyles?.featureEdges },
|
|
184
188
|
stairArrows: { ...DEFAULT_SVG_STYLES.stairArrows, ...userStyles?.stairArrows },
|
|
185
189
|
outlineVisible: { ...DEFAULT_SVG_STYLES.outlineVisible, ...userStyles?.outlineVisible },
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shipped `templates/template-schema.json` contains VS Code snippet
|
|
3
|
+
* placeholders (`${1:value}`) inside `defaultSnippets` bodies — valid for
|
|
4
|
+
* Monaco/VS Code, but not strict JSON. Consumers that need to parse the
|
|
5
|
+
* schema (ajv validation, editors without snippet support) must strip them
|
|
6
|
+
* first; this is the one shared implementation.
|
|
7
|
+
*/
|
|
8
|
+
export function sanitizeTemplateSchemaSnippets(schemaJsonText: string): string {
|
|
9
|
+
return schemaJsonText
|
|
10
|
+
.replace(/\$\{\d+:(-?[\d.]+)\}/g, '$1') // ${1:420} -> 420
|
|
11
|
+
.replace(/\$\{\d+:([^}"]*)\}/g, '$1') // ${2:main} -> main
|
|
12
|
+
.replace(/\$\{\d+\}|\$\d+/g, ''); // ${3} / $0 -> (removed)
|
|
13
|
+
}
|
|
@@ -1,11 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "a3-landscape-with-logo",
|
|
3
|
-
"page": {
|
|
3
|
+
"page": {
|
|
4
|
+
"widthMm": 420,
|
|
5
|
+
"heightMm": 297,
|
|
6
|
+
"marginMm": 10,
|
|
7
|
+
"backgroundColor": "#ffffff"
|
|
8
|
+
},
|
|
4
9
|
"styles": {
|
|
5
|
-
"body": {
|
|
10
|
+
"body": {
|
|
11
|
+
"fontFamily": "Arial",
|
|
12
|
+
"fontSizeMm": 3.5
|
|
13
|
+
}
|
|
6
14
|
},
|
|
7
|
-
"
|
|
8
|
-
|
|
15
|
+
"allowRemoteResources": true,
|
|
16
|
+
"resources": [
|
|
17
|
+
{
|
|
18
|
+
"id": "logo-main",
|
|
19
|
+
"src": "https://twinfinity.com/theme-assets/logo.svg"
|
|
20
|
+
}
|
|
9
21
|
],
|
|
10
22
|
"elements": [
|
|
11
23
|
{
|
|
@@ -15,7 +27,7 @@
|
|
|
15
27
|
"yMm": 10,
|
|
16
28
|
"widthMm": 80,
|
|
17
29
|
"heightMm": 20,
|
|
18
|
-
"
|
|
30
|
+
"resourceId": "logo-main",
|
|
19
31
|
"fit": "contain"
|
|
20
32
|
},
|
|
21
33
|
{
|
|
@@ -47,9 +59,19 @@
|
|
|
47
59
|
"widthMm": 410,
|
|
48
60
|
"heightMm": 230,
|
|
49
61
|
"scaleMode": "fitAndRound",
|
|
50
|
-
"preferredScales": [
|
|
51
|
-
|
|
52
|
-
|
|
62
|
+
"preferredScales": [
|
|
63
|
+
2,
|
|
64
|
+
10,
|
|
65
|
+
25,
|
|
66
|
+
50,
|
|
67
|
+
100,
|
|
68
|
+
150,
|
|
69
|
+
250,
|
|
70
|
+
500,
|
|
71
|
+
1000,
|
|
72
|
+
2500
|
|
73
|
+
],
|
|
74
|
+
"align": "center"
|
|
53
75
|
},
|
|
54
76
|
{
|
|
55
77
|
"kind": "scaleBar",
|
package/src/types.ts
CHANGED
|
@@ -12,7 +12,8 @@ export interface SvgRenderStyles {
|
|
|
12
12
|
cutLines?: SvgLineStyle;
|
|
13
13
|
visibleLines?: SvgLineStyle;
|
|
14
14
|
hiddenLines?: SvgLineStyle;
|
|
15
|
-
|
|
15
|
+
silhouettesVisible?: SvgLineStyle;
|
|
16
|
+
silhouettesHidden?: SvgLineStyle;
|
|
16
17
|
featureEdges?: SvgLineStyle;
|
|
17
18
|
stairArrows?: SvgLineStyle;
|
|
18
19
|
outlineVisible?: SvgLineStyle;
|
|
@@ -41,7 +42,16 @@ export const DEFAULT_SVG_STYLES: Required<SvgRenderStyles> = {
|
|
|
41
42
|
cutLines: { enabled: true, stroke: '#dc2626', strokeWidth: 0.01, opacity: 1 },
|
|
42
43
|
visibleLines: { enabled: true, stroke: '#111827', strokeWidth: 0.005, opacity: 1 },
|
|
43
44
|
hiddenLines: { enabled: true, stroke: '#6b7280', strokeWidth: 0.004, strokeDasharray: '0.02,0.01', opacity: 1 },
|
|
44
|
-
|
|
45
|
+
silhouettesVisible: { enabled: true, stroke: '#000000', strokeWidth: 0.006, opacity: 1 },
|
|
46
|
+
// Hidden contours follow the hiddenLines drafting convention (dashed grey), not the
|
|
47
|
+
// visible outline's heavy solid stroke.
|
|
48
|
+
silhouettesHidden: {
|
|
49
|
+
enabled: true,
|
|
50
|
+
stroke: '#6b7280',
|
|
51
|
+
strokeWidth: 0.004,
|
|
52
|
+
strokeDasharray: '0.02,0.01',
|
|
53
|
+
opacity: 1
|
|
54
|
+
},
|
|
45
55
|
featureEdges: { enabled: true, stroke: '#374151', strokeWidth: 0.005, opacity: 1 },
|
|
46
56
|
stairArrows: { enabled: true, stroke: '#111827', strokeWidth: 0.005, opacity: 1 },
|
|
47
57
|
outlineVisible: { enabled: true, stroke: '#111827', strokeWidth: 0.004, opacity: 1 },
|
|
@@ -3,20 +3,58 @@
|
|
|
3
3
|
"id": "default-a0-landscape",
|
|
4
4
|
"presets": {
|
|
5
5
|
"includeClasses": {
|
|
6
|
-
"defaultBuilding": [
|
|
6
|
+
"defaultBuilding": [
|
|
7
|
+
"space",
|
|
8
|
+
"walls",
|
|
9
|
+
"windows",
|
|
10
|
+
"doors",
|
|
11
|
+
"beam",
|
|
12
|
+
"columns",
|
|
13
|
+
"stairs",
|
|
14
|
+
"floor"
|
|
15
|
+
]
|
|
7
16
|
},
|
|
8
17
|
"scales": {
|
|
9
|
-
"default": {
|
|
18
|
+
"default": {
|
|
19
|
+
"preferredScales": [
|
|
20
|
+
2,
|
|
21
|
+
10,
|
|
22
|
+
25,
|
|
23
|
+
50,
|
|
24
|
+
100,
|
|
25
|
+
150,
|
|
26
|
+
250,
|
|
27
|
+
500,
|
|
28
|
+
1000,
|
|
29
|
+
2500
|
|
30
|
+
]
|
|
31
|
+
}
|
|
10
32
|
}
|
|
11
33
|
},
|
|
12
|
-
"page": {
|
|
34
|
+
"page": {
|
|
35
|
+
"widthMm": 1189,
|
|
36
|
+
"heightMm": 841,
|
|
37
|
+
"marginMm": 5,
|
|
38
|
+
"backgroundColor": "#ffffff"
|
|
39
|
+
},
|
|
13
40
|
"styles": {
|
|
14
|
-
"body": {
|
|
15
|
-
|
|
41
|
+
"body": {
|
|
42
|
+
"fontFamily": "Arial",
|
|
43
|
+
"fontSizeMm": 3.5,
|
|
44
|
+
"color": "#000000"
|
|
45
|
+
},
|
|
46
|
+
"spaceLabels": {
|
|
47
|
+
"fontFamily": "Arial",
|
|
48
|
+
"fontSizeMm": 5,
|
|
49
|
+
"color": "#000000"
|
|
50
|
+
}
|
|
16
51
|
},
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
{
|
|
52
|
+
"allowRemoteResources": true,
|
|
53
|
+
"resources": [
|
|
54
|
+
{
|
|
55
|
+
"id": "logo-main",
|
|
56
|
+
"src": "https://twinfinity.com/theme-assets/logo.svg"
|
|
57
|
+
}
|
|
20
58
|
],
|
|
21
59
|
"elements": [
|
|
22
60
|
{
|
|
@@ -26,7 +64,7 @@
|
|
|
26
64
|
"yMm": 7,
|
|
27
65
|
"widthMm": 40,
|
|
28
66
|
"heightMm": 10,
|
|
29
|
-
"
|
|
67
|
+
"resourceId": "logo-main",
|
|
30
68
|
"fit": "contain"
|
|
31
69
|
},
|
|
32
70
|
{
|
|
@@ -47,19 +85,38 @@
|
|
|
47
85
|
"yMm": 20,
|
|
48
86
|
"widthMm": 1179,
|
|
49
87
|
"heightMm": 794,
|
|
50
|
-
"includeClasses": {
|
|
88
|
+
"includeClasses": {
|
|
89
|
+
"preset": "defaultBuilding"
|
|
90
|
+
},
|
|
51
91
|
"scaleMode": "fitAndRound",
|
|
52
92
|
"scalePreset": "default",
|
|
53
93
|
"align": "center",
|
|
54
|
-
"
|
|
55
|
-
|
|
94
|
+
"fills": [
|
|
95
|
+
{
|
|
96
|
+
"class": "space",
|
|
97
|
+
"fill": "sample",
|
|
98
|
+
"fillOpacity": 0.35
|
|
99
|
+
}
|
|
100
|
+
],
|
|
56
101
|
"lineStyles": {
|
|
57
|
-
"default":
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
102
|
+
"default": {
|
|
103
|
+
"widthMm": 0.25,
|
|
104
|
+
"color": "#1f2937"
|
|
105
|
+
},
|
|
106
|
+
"visibleLines": {
|
|
107
|
+
"widthMm": 0.25,
|
|
108
|
+
"color": "#1f2937"
|
|
109
|
+
},
|
|
110
|
+
"hiddenLines": {
|
|
111
|
+
"widthMm": 0.13,
|
|
112
|
+
"color": "#9ca3af",
|
|
113
|
+
"dash": "4 2"
|
|
114
|
+
},
|
|
115
|
+
"stairArrows": {
|
|
116
|
+
"widthMm": 0.35,
|
|
117
|
+
"color": "#1f2937"
|
|
118
|
+
}
|
|
119
|
+
}
|
|
63
120
|
},
|
|
64
121
|
{
|
|
65
122
|
"kind": "text",
|
|
@@ -96,114 +153,162 @@
|
|
|
96
153
|
{
|
|
97
154
|
"kind": "line",
|
|
98
155
|
"id": "fold-v-29-top",
|
|
99
|
-
"x1Mm": 29,
|
|
100
|
-
"
|
|
101
|
-
"
|
|
156
|
+
"x1Mm": 29,
|
|
157
|
+
"y1Mm": 2,
|
|
158
|
+
"x2Mm": 29,
|
|
159
|
+
"y2Mm": 8,
|
|
160
|
+
"stroke": "#000",
|
|
161
|
+
"strokeWidthMm": 0.2
|
|
102
162
|
},
|
|
103
163
|
{
|
|
104
164
|
"kind": "line",
|
|
105
165
|
"id": "fold-v-29-bottom",
|
|
106
|
-
"x1Mm": 29,
|
|
107
|
-
"
|
|
108
|
-
"
|
|
166
|
+
"x1Mm": 29,
|
|
167
|
+
"y1Mm": 828,
|
|
168
|
+
"x2Mm": 29,
|
|
169
|
+
"y2Mm": 834,
|
|
170
|
+
"stroke": "#000",
|
|
171
|
+
"strokeWidthMm": 0.2
|
|
109
172
|
},
|
|
110
173
|
{
|
|
111
174
|
"kind": "line",
|
|
112
175
|
"id": "fold-v-219-top",
|
|
113
|
-
"x1Mm": 219,
|
|
114
|
-
"
|
|
115
|
-
"
|
|
176
|
+
"x1Mm": 219,
|
|
177
|
+
"y1Mm": 2,
|
|
178
|
+
"x2Mm": 219,
|
|
179
|
+
"y2Mm": 8,
|
|
180
|
+
"stroke": "#000",
|
|
181
|
+
"strokeWidthMm": 0.2
|
|
116
182
|
},
|
|
117
183
|
{
|
|
118
184
|
"kind": "line",
|
|
119
185
|
"id": "fold-v-219-bottom",
|
|
120
|
-
"x1Mm": 219,
|
|
121
|
-
"
|
|
122
|
-
"
|
|
186
|
+
"x1Mm": 219,
|
|
187
|
+
"y1Mm": 828,
|
|
188
|
+
"x2Mm": 219,
|
|
189
|
+
"y2Mm": 834,
|
|
190
|
+
"stroke": "#000",
|
|
191
|
+
"strokeWidthMm": 0.2
|
|
123
192
|
},
|
|
124
193
|
{
|
|
125
194
|
"kind": "line",
|
|
126
195
|
"id": "fold-v-409-top",
|
|
127
|
-
"x1Mm": 409,
|
|
128
|
-
"
|
|
129
|
-
"
|
|
196
|
+
"x1Mm": 409,
|
|
197
|
+
"y1Mm": 2,
|
|
198
|
+
"x2Mm": 409,
|
|
199
|
+
"y2Mm": 8,
|
|
200
|
+
"stroke": "#000",
|
|
201
|
+
"strokeWidthMm": 0.2
|
|
130
202
|
},
|
|
131
203
|
{
|
|
132
204
|
"kind": "line",
|
|
133
205
|
"id": "fold-v-409-bottom",
|
|
134
|
-
"x1Mm": 409,
|
|
135
|
-
"
|
|
136
|
-
"
|
|
206
|
+
"x1Mm": 409,
|
|
207
|
+
"y1Mm": 828,
|
|
208
|
+
"x2Mm": 409,
|
|
209
|
+
"y2Mm": 834,
|
|
210
|
+
"stroke": "#000",
|
|
211
|
+
"strokeWidthMm": 0.2
|
|
137
212
|
},
|
|
138
213
|
{
|
|
139
214
|
"kind": "line",
|
|
140
215
|
"id": "fold-v-599-top",
|
|
141
|
-
"x1Mm": 599,
|
|
142
|
-
"
|
|
143
|
-
"
|
|
216
|
+
"x1Mm": 599,
|
|
217
|
+
"y1Mm": 2,
|
|
218
|
+
"x2Mm": 599,
|
|
219
|
+
"y2Mm": 8,
|
|
220
|
+
"stroke": "#000",
|
|
221
|
+
"strokeWidthMm": 0.2
|
|
144
222
|
},
|
|
145
223
|
{
|
|
146
224
|
"kind": "line",
|
|
147
225
|
"id": "fold-v-599-bottom",
|
|
148
|
-
"x1Mm": 599,
|
|
149
|
-
"
|
|
150
|
-
"
|
|
226
|
+
"x1Mm": 599,
|
|
227
|
+
"y1Mm": 828,
|
|
228
|
+
"x2Mm": 599,
|
|
229
|
+
"y2Mm": 834,
|
|
230
|
+
"stroke": "#000",
|
|
231
|
+
"strokeWidthMm": 0.2
|
|
151
232
|
},
|
|
152
233
|
{
|
|
153
234
|
"kind": "line",
|
|
154
235
|
"id": "fold-v-789-top",
|
|
155
|
-
"x1Mm": 789,
|
|
156
|
-
"
|
|
157
|
-
"
|
|
236
|
+
"x1Mm": 789,
|
|
237
|
+
"y1Mm": 2,
|
|
238
|
+
"x2Mm": 789,
|
|
239
|
+
"y2Mm": 8,
|
|
240
|
+
"stroke": "#000",
|
|
241
|
+
"strokeWidthMm": 0.2
|
|
158
242
|
},
|
|
159
243
|
{
|
|
160
244
|
"kind": "line",
|
|
161
245
|
"id": "fold-v-789-bottom",
|
|
162
|
-
"x1Mm": 789,
|
|
163
|
-
"
|
|
164
|
-
"
|
|
246
|
+
"x1Mm": 789,
|
|
247
|
+
"y1Mm": 828,
|
|
248
|
+
"x2Mm": 789,
|
|
249
|
+
"y2Mm": 834,
|
|
250
|
+
"stroke": "#000",
|
|
251
|
+
"strokeWidthMm": 0.2
|
|
165
252
|
},
|
|
166
253
|
{
|
|
167
254
|
"kind": "line",
|
|
168
255
|
"id": "fold-v-979-top",
|
|
169
|
-
"x1Mm": 979,
|
|
170
|
-
"
|
|
171
|
-
"
|
|
256
|
+
"x1Mm": 979,
|
|
257
|
+
"y1Mm": 2,
|
|
258
|
+
"x2Mm": 979,
|
|
259
|
+
"y2Mm": 8,
|
|
260
|
+
"stroke": "#000",
|
|
261
|
+
"strokeWidthMm": 0.2
|
|
172
262
|
},
|
|
173
263
|
{
|
|
174
264
|
"kind": "line",
|
|
175
265
|
"id": "fold-v-979-bottom",
|
|
176
|
-
"x1Mm": 979,
|
|
177
|
-
"
|
|
178
|
-
"
|
|
266
|
+
"x1Mm": 979,
|
|
267
|
+
"y1Mm": 828,
|
|
268
|
+
"x2Mm": 979,
|
|
269
|
+
"y2Mm": 834,
|
|
270
|
+
"stroke": "#000",
|
|
271
|
+
"strokeWidthMm": 0.2
|
|
179
272
|
},
|
|
180
273
|
{
|
|
181
274
|
"kind": "line",
|
|
182
275
|
"id": "fold-h-247-left",
|
|
183
|
-
"x1Mm": 2,
|
|
184
|
-
"
|
|
185
|
-
"
|
|
276
|
+
"x1Mm": 2,
|
|
277
|
+
"y1Mm": 247,
|
|
278
|
+
"x2Mm": 8,
|
|
279
|
+
"y2Mm": 247,
|
|
280
|
+
"stroke": "#000",
|
|
281
|
+
"strokeWidthMm": 0.2
|
|
186
282
|
},
|
|
187
283
|
{
|
|
188
284
|
"kind": "line",
|
|
189
285
|
"id": "fold-h-247-right",
|
|
190
|
-
"x1Mm": 1176,
|
|
191
|
-
"
|
|
192
|
-
"
|
|
286
|
+
"x1Mm": 1176,
|
|
287
|
+
"y1Mm": 247,
|
|
288
|
+
"x2Mm": 1182,
|
|
289
|
+
"y2Mm": 247,
|
|
290
|
+
"stroke": "#000",
|
|
291
|
+
"strokeWidthMm": 0.2
|
|
193
292
|
},
|
|
194
293
|
{
|
|
195
294
|
"kind": "line",
|
|
196
295
|
"id": "fold-h-544-left",
|
|
197
|
-
"x1Mm": 2,
|
|
198
|
-
"
|
|
199
|
-
"
|
|
296
|
+
"x1Mm": 2,
|
|
297
|
+
"y1Mm": 544,
|
|
298
|
+
"x2Mm": 8,
|
|
299
|
+
"y2Mm": 544,
|
|
300
|
+
"stroke": "#000",
|
|
301
|
+
"strokeWidthMm": 0.2
|
|
200
302
|
},
|
|
201
303
|
{
|
|
202
304
|
"kind": "line",
|
|
203
305
|
"id": "fold-h-544-right",
|
|
204
|
-
"x1Mm": 1176,
|
|
205
|
-
"
|
|
206
|
-
"
|
|
306
|
+
"x1Mm": 1176,
|
|
307
|
+
"y1Mm": 544,
|
|
308
|
+
"x2Mm": 1182,
|
|
309
|
+
"y2Mm": 544,
|
|
310
|
+
"stroke": "#000",
|
|
311
|
+
"strokeWidthMm": 0.2
|
|
207
312
|
}
|
|
208
313
|
]
|
|
209
314
|
}
|