@ifc-lite/drawing-2d 1.4.0
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/LICENSE +373 -0
- package/dist/drawing-generator.d.ts +80 -0
- package/dist/drawing-generator.d.ts.map +1 -0
- package/dist/drawing-generator.js +281 -0
- package/dist/drawing-generator.js.map +1 -0
- package/dist/edge-extractor.d.ts +47 -0
- package/dist/edge-extractor.d.ts.map +1 -0
- package/dist/edge-extractor.js +204 -0
- package/dist/edge-extractor.js.map +1 -0
- package/dist/gpu-section-cutter.d.ts +42 -0
- package/dist/gpu-section-cutter.d.ts.map +1 -0
- package/dist/gpu-section-cutter.js +405 -0
- package/dist/gpu-section-cutter.js.map +1 -0
- package/dist/graphic-overrides/index.d.ts +10 -0
- package/dist/graphic-overrides/index.d.ts.map +1 -0
- package/dist/graphic-overrides/index.js +8 -0
- package/dist/graphic-overrides/index.js.map +1 -0
- package/dist/graphic-overrides/presets.d.ts +22 -0
- package/dist/graphic-overrides/presets.d.ts.map +1 -0
- package/dist/graphic-overrides/presets.js +283 -0
- package/dist/graphic-overrides/presets.js.map +1 -0
- package/dist/graphic-overrides/rule-engine.d.ts +64 -0
- package/dist/graphic-overrides/rule-engine.d.ts.map +1 -0
- package/dist/graphic-overrides/rule-engine.js +438 -0
- package/dist/graphic-overrides/rule-engine.js.map +1 -0
- package/dist/graphic-overrides/types.d.ts +200 -0
- package/dist/graphic-overrides/types.d.ts.map +1 -0
- package/dist/graphic-overrides/types.js +5 -0
- package/dist/graphic-overrides/types.js.map +1 -0
- package/dist/hatch-generator.d.ts +76 -0
- package/dist/hatch-generator.d.ts.map +1 -0
- package/dist/hatch-generator.js +282 -0
- package/dist/hatch-generator.js.map +1 -0
- package/dist/hidden-line.d.ts +64 -0
- package/dist/hidden-line.d.ts.map +1 -0
- package/dist/hidden-line.js +318 -0
- package/dist/hidden-line.js.map +1 -0
- package/dist/index.d.ts +44 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +109 -0
- package/dist/index.js.map +1 -0
- package/dist/line-merger.d.ts +35 -0
- package/dist/line-merger.d.ts.map +1 -0
- package/dist/line-merger.js +265 -0
- package/dist/line-merger.js.map +1 -0
- package/dist/math.d.ts +90 -0
- package/dist/math.d.ts.map +1 -0
- package/dist/math.js +284 -0
- package/dist/math.js.map +1 -0
- package/dist/openings/index.d.ts +7 -0
- package/dist/openings/index.d.ts.map +1 -0
- package/dist/openings/index.js +10 -0
- package/dist/openings/index.js.map +1 -0
- package/dist/openings/opening-filter.d.ts +61 -0
- package/dist/openings/opening-filter.d.ts.map +1 -0
- package/dist/openings/opening-filter.js +244 -0
- package/dist/openings/opening-filter.js.map +1 -0
- package/dist/openings/opening-relationship-builder.d.ts +35 -0
- package/dist/openings/opening-relationship-builder.d.ts.map +1 -0
- package/dist/openings/opening-relationship-builder.js +121 -0
- package/dist/openings/opening-relationship-builder.js.map +1 -0
- package/dist/openings/opening-utils.d.ts +55 -0
- package/dist/openings/opening-utils.d.ts.map +1 -0
- package/dist/openings/opening-utils.js +128 -0
- package/dist/openings/opening-utils.js.map +1 -0
- package/dist/polygon-builder.d.ts +62 -0
- package/dist/polygon-builder.d.ts.map +1 -0
- package/dist/polygon-builder.js +261 -0
- package/dist/polygon-builder.js.map +1 -0
- package/dist/section-cutter.d.ts +49 -0
- package/dist/section-cutter.d.ts.map +1 -0
- package/dist/section-cutter.js +220 -0
- package/dist/section-cutter.js.map +1 -0
- package/dist/sheet/frame-renderer.d.ts +28 -0
- package/dist/sheet/frame-renderer.d.ts.map +1 -0
- package/dist/sheet/frame-renderer.js +199 -0
- package/dist/sheet/frame-renderer.js.map +1 -0
- package/dist/sheet/frame-types.d.ts +57 -0
- package/dist/sheet/frame-types.d.ts.map +1 -0
- package/dist/sheet/frame-types.js +88 -0
- package/dist/sheet/frame-types.js.map +1 -0
- package/dist/sheet/index.d.ts +26 -0
- package/dist/sheet/index.d.ts.map +1 -0
- package/dist/sheet/index.js +12 -0
- package/dist/sheet/index.js.map +1 -0
- package/dist/sheet/paper-sizes.d.ts +36 -0
- package/dist/sheet/paper-sizes.d.ts.map +1 -0
- package/dist/sheet/paper-sizes.js +252 -0
- package/dist/sheet/paper-sizes.js.map +1 -0
- package/dist/sheet/scale-bar-renderer.d.ts +29 -0
- package/dist/sheet/scale-bar-renderer.d.ts.map +1 -0
- package/dist/sheet/scale-bar-renderer.js +287 -0
- package/dist/sheet/scale-bar-renderer.js.map +1 -0
- package/dist/sheet/scale-bar-types.d.ts +82 -0
- package/dist/sheet/scale-bar-types.d.ts.map +1 -0
- package/dist/sheet/scale-bar-types.js +66 -0
- package/dist/sheet/scale-bar-types.js.map +1 -0
- package/dist/sheet/sheet-types.d.ts +84 -0
- package/dist/sheet/sheet-types.d.ts.map +1 -0
- package/dist/sheet/sheet-types.js +77 -0
- package/dist/sheet/sheet-types.js.map +1 -0
- package/dist/sheet/title-block-renderer.d.ts +44 -0
- package/dist/sheet/title-block-renderer.d.ts.map +1 -0
- package/dist/sheet/title-block-renderer.js +335 -0
- package/dist/sheet/title-block-renderer.js.map +1 -0
- package/dist/sheet/title-block-types.d.ts +100 -0
- package/dist/sheet/title-block-types.d.ts.map +1 -0
- package/dist/sheet/title-block-types.js +174 -0
- package/dist/sheet/title-block-types.js.map +1 -0
- package/dist/styles.d.ts +77 -0
- package/dist/styles.d.ts.map +1 -0
- package/dist/styles.js +347 -0
- package/dist/styles.js.map +1 -0
- package/dist/styling/index.d.ts +7 -0
- package/dist/styling/index.d.ts.map +1 -0
- package/dist/styling/index.js +10 -0
- package/dist/styling/index.js.map +1 -0
- package/dist/styling/layer-mapping.d.ts +57 -0
- package/dist/styling/layer-mapping.d.ts.map +1 -0
- package/dist/styling/layer-mapping.js +303 -0
- package/dist/styling/layer-mapping.js.map +1 -0
- package/dist/styling/line-styles.d.ts +49 -0
- package/dist/styling/line-styles.d.ts.map +1 -0
- package/dist/styling/line-styles.js +123 -0
- package/dist/styling/line-styles.js.map +1 -0
- package/dist/styling/line-weights.d.ts +61 -0
- package/dist/styling/line-weights.d.ts.map +1 -0
- package/dist/styling/line-weights.js +183 -0
- package/dist/styling/line-weights.js.map +1 -0
- package/dist/svg-exporter.d.ts +63 -0
- package/dist/svg-exporter.d.ts.map +1 -0
- package/dist/svg-exporter.js +278 -0
- package/dist/svg-exporter.js.map +1 -0
- package/dist/symbols/door-symbol.d.ts +82 -0
- package/dist/symbols/door-symbol.d.ts.map +1 -0
- package/dist/symbols/door-symbol.js +390 -0
- package/dist/symbols/door-symbol.js.map +1 -0
- package/dist/symbols/index.d.ts +8 -0
- package/dist/symbols/index.d.ts.map +1 -0
- package/dist/symbols/index.js +11 -0
- package/dist/symbols/index.js.map +1 -0
- package/dist/symbols/symbol-renderer.d.ts +29 -0
- package/dist/symbols/symbol-renderer.d.ts.map +1 -0
- package/dist/symbols/symbol-renderer.js +173 -0
- package/dist/symbols/symbol-renderer.js.map +1 -0
- package/dist/symbols/symbol-utils.d.ts +48 -0
- package/dist/symbols/symbol-utils.d.ts.map +1 -0
- package/dist/symbols/symbol-utils.js +129 -0
- package/dist/symbols/symbol-utils.js.map +1 -0
- package/dist/symbols/window-symbol.d.ts +57 -0
- package/dist/symbols/window-symbol.d.ts.map +1 -0
- package/dist/symbols/window-symbol.js +209 -0
- package/dist/symbols/window-symbol.js.map +1 -0
- package/dist/types.d.ts +443 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +31 -0
- package/dist/types.js.map +1 -0
- package/package.json +53 -0
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { DEFAULT_SECTION_CONFIG } from './types';
|
|
5
|
+
import { SectionCutter } from './section-cutter';
|
|
6
|
+
import { PolygonBuilder } from './polygon-builder';
|
|
7
|
+
import { EdgeExtractor, getViewDirection } from './edge-extractor';
|
|
8
|
+
import { HiddenLineClassifier } from './hidden-line';
|
|
9
|
+
import { mergeDrawingLines } from './line-merger';
|
|
10
|
+
import { HatchGenerator } from './hatch-generator';
|
|
11
|
+
import { SVGExporter } from './svg-exporter';
|
|
12
|
+
import { GPUSectionCutter } from './gpu-section-cutter';
|
|
13
|
+
import { boundsEmpty, boundsExtendLine, lineLength, } from './math';
|
|
14
|
+
const DEFAULT_OPTIONS = {
|
|
15
|
+
useGPU: true,
|
|
16
|
+
includeHiddenLines: true,
|
|
17
|
+
includeProjection: true,
|
|
18
|
+
includeEdges: true,
|
|
19
|
+
mergeLines: true,
|
|
20
|
+
};
|
|
21
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
22
|
+
// DRAWING GENERATOR CLASS
|
|
23
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
24
|
+
export class Drawing2DGenerator {
|
|
25
|
+
gpuCutter = null;
|
|
26
|
+
cpuCutter = null;
|
|
27
|
+
polygonBuilder = new PolygonBuilder();
|
|
28
|
+
edgeExtractor = new EdgeExtractor(30); // 30° crease angle
|
|
29
|
+
hiddenLineClassifier = new HiddenLineClassifier({ resolution: 1024 });
|
|
30
|
+
hatchGenerator = new HatchGenerator();
|
|
31
|
+
svgExporter = new SVGExporter();
|
|
32
|
+
gpuDevice = null;
|
|
33
|
+
initialized = false;
|
|
34
|
+
/**
|
|
35
|
+
* Initialize the generator with optional GPU device
|
|
36
|
+
*/
|
|
37
|
+
async initialize(gpuDevice) {
|
|
38
|
+
if (gpuDevice) {
|
|
39
|
+
this.gpuDevice = gpuDevice;
|
|
40
|
+
this.gpuCutter = new GPUSectionCutter(gpuDevice);
|
|
41
|
+
await this.gpuCutter.initialize(100000); // Initial capacity
|
|
42
|
+
}
|
|
43
|
+
this.initialized = true;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Generate a complete 2D drawing from meshes
|
|
47
|
+
*/
|
|
48
|
+
async generate(meshes, config, options = {}) {
|
|
49
|
+
const opts = { ...DEFAULT_OPTIONS, ...options };
|
|
50
|
+
const startTime = performance.now();
|
|
51
|
+
const report = (stage, progress) => {
|
|
52
|
+
opts.onProgress?.(stage, progress);
|
|
53
|
+
};
|
|
54
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
55
|
+
// STAGE 1: Section Cutting
|
|
56
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
57
|
+
report('cutting', 0);
|
|
58
|
+
let cutSegments;
|
|
59
|
+
if (opts.useGPU && this.gpuCutter && this.gpuDevice) {
|
|
60
|
+
// GPU path
|
|
61
|
+
cutSegments = await this.gpuCutter.cutMeshes(meshes, config.plane);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
// CPU path
|
|
65
|
+
if (!this.cpuCutter || this.cpuCutter === null) {
|
|
66
|
+
this.cpuCutter = new SectionCutter(config.plane);
|
|
67
|
+
}
|
|
68
|
+
const cutResult = this.cpuCutter.cutMeshes(meshes);
|
|
69
|
+
cutSegments = cutResult.segments;
|
|
70
|
+
}
|
|
71
|
+
report('cutting', 1);
|
|
72
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
73
|
+
// STAGE 2: Polygon Reconstruction
|
|
74
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
75
|
+
report('polygons', 0);
|
|
76
|
+
const cutPolygons = this.polygonBuilder.buildPolygons(cutSegments);
|
|
77
|
+
report('polygons', 1);
|
|
78
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
79
|
+
// STAGE 3: Convert Cut Segments to Drawing Lines
|
|
80
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
81
|
+
const cutLines = cutSegments.map((seg) => ({
|
|
82
|
+
line: { start: seg.p0_2d, end: seg.p1_2d },
|
|
83
|
+
category: 'cut',
|
|
84
|
+
visibility: 'visible',
|
|
85
|
+
entityId: seg.entityId,
|
|
86
|
+
ifcType: seg.ifcType,
|
|
87
|
+
modelIndex: seg.modelIndex,
|
|
88
|
+
depth: 0,
|
|
89
|
+
}));
|
|
90
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
91
|
+
// STAGE 4: Edge Extraction (Projection Lines)
|
|
92
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
93
|
+
let projectionLines = [];
|
|
94
|
+
let silhouetteLines = [];
|
|
95
|
+
if (opts.includeProjection || opts.includeEdges) {
|
|
96
|
+
report('edges', 0);
|
|
97
|
+
// Extract feature edges from all meshes
|
|
98
|
+
const allEdges = this.edgeExtractor.extractEdgesFromMeshes(meshes);
|
|
99
|
+
// Filter edges in projection range
|
|
100
|
+
const projectionEdges = this.edgeExtractor.filterEdgesByDepth(allEdges, config.plane.axis, config.plane.position, config.projectionDepth, config.plane.flipped);
|
|
101
|
+
// Get view direction for silhouette detection
|
|
102
|
+
const viewDir = getViewDirection(config.plane.axis, config.plane.flipped);
|
|
103
|
+
// Extract silhouettes
|
|
104
|
+
const silhouettes = this.edgeExtractor.extractSilhouettes(projectionEdges, viewDir);
|
|
105
|
+
// Convert to drawing lines
|
|
106
|
+
if (opts.includeEdges) {
|
|
107
|
+
silhouetteLines = this.edgeExtractor.edgesToDrawingLines(silhouettes, config.plane.axis, config.plane.flipped, 'silhouette', config.plane.position);
|
|
108
|
+
}
|
|
109
|
+
// Non-silhouette feature edges become projection lines
|
|
110
|
+
if (opts.includeProjection) {
|
|
111
|
+
const creaseEdges = projectionEdges.filter((e) => e.type === 'crease' && !silhouettes.includes(e));
|
|
112
|
+
projectionLines = this.edgeExtractor.edgesToDrawingLines(creaseEdges, config.plane.axis, config.plane.flipped, 'projection', config.plane.position);
|
|
113
|
+
}
|
|
114
|
+
// Filter out outlier lines that are abnormally long (likely artifacts)
|
|
115
|
+
// Use cut polygon bounds to determine reasonable max line length
|
|
116
|
+
const cutBounds = this.computeBounds(cutLines);
|
|
117
|
+
if (cutBounds.min.x < cutBounds.max.x && cutBounds.min.y < cutBounds.max.y) {
|
|
118
|
+
const boundsWidth = cutBounds.max.x - cutBounds.min.x;
|
|
119
|
+
const boundsHeight = cutBounds.max.y - cutBounds.min.y;
|
|
120
|
+
const boundsDiagonal = Math.sqrt(boundsWidth * boundsWidth + boundsHeight * boundsHeight);
|
|
121
|
+
// Allow lines up to 1.5x the diagonal of the cut area
|
|
122
|
+
const maxLineLength = boundsDiagonal * 1.5;
|
|
123
|
+
silhouetteLines = silhouetteLines.filter((line) => lineLength(line.line) <= maxLineLength);
|
|
124
|
+
projectionLines = projectionLines.filter((line) => lineLength(line.line) <= maxLineLength);
|
|
125
|
+
}
|
|
126
|
+
report('edges', 1);
|
|
127
|
+
}
|
|
128
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
129
|
+
// STAGE 5: Hidden Line Removal
|
|
130
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
131
|
+
let allLines = [...cutLines, ...projectionLines, ...silhouetteLines];
|
|
132
|
+
if (opts.includeHiddenLines && (projectionLines.length > 0 || silhouetteLines.length > 0)) {
|
|
133
|
+
report('hidden', 0);
|
|
134
|
+
// Compute bounds for depth buffer
|
|
135
|
+
const bounds = this.computeBounds(allLines);
|
|
136
|
+
// Build depth buffer and classify lines
|
|
137
|
+
this.hiddenLineClassifier.buildDepthBuffer(meshes, config.plane.axis, config.plane.position, config.projectionDepth, config.plane.flipped, bounds);
|
|
138
|
+
// Only classify non-cut lines
|
|
139
|
+
const linesToClassify = allLines.filter((l) => l.category !== 'cut');
|
|
140
|
+
const classifiedLines = this.hiddenLineClassifier.applyVisibility(linesToClassify);
|
|
141
|
+
// Recombine with cut lines (always visible)
|
|
142
|
+
allLines = [...cutLines, ...classifiedLines];
|
|
143
|
+
report('hidden', 1);
|
|
144
|
+
}
|
|
145
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
146
|
+
// STAGE 6: Line Merging
|
|
147
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
148
|
+
if (opts.mergeLines) {
|
|
149
|
+
report('merging', 0);
|
|
150
|
+
allLines = mergeDrawingLines(allLines);
|
|
151
|
+
report('merging', 1);
|
|
152
|
+
}
|
|
153
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
154
|
+
// FINALIZE
|
|
155
|
+
// ─────────────────────────────────────────────────────────────────────────
|
|
156
|
+
const bounds = this.computeBounds(allLines);
|
|
157
|
+
const processingTimeMs = performance.now() - startTime;
|
|
158
|
+
// Count line categories
|
|
159
|
+
const cutLineCount = allLines.filter((l) => l.category === 'cut').length;
|
|
160
|
+
const projectionLineCount = allLines.filter((l) => l.category === 'projection').length;
|
|
161
|
+
const hiddenLineCount = allLines.filter((l) => l.visibility === 'hidden').length;
|
|
162
|
+
const silhouetteLineCount = allLines.filter((l) => l.category === 'silhouette').length;
|
|
163
|
+
report('complete', 1);
|
|
164
|
+
return {
|
|
165
|
+
config,
|
|
166
|
+
lines: allLines,
|
|
167
|
+
cutPolygons,
|
|
168
|
+
projectionPolygons: [], // TODO: implement projection polygon extraction
|
|
169
|
+
bounds,
|
|
170
|
+
stats: {
|
|
171
|
+
cutLineCount,
|
|
172
|
+
projectionLineCount,
|
|
173
|
+
hiddenLineCount,
|
|
174
|
+
silhouetteLineCount,
|
|
175
|
+
polygonCount: cutPolygons.length,
|
|
176
|
+
totalTriangles: meshes.reduce((sum, m) => sum + m.indices.length / 3, 0),
|
|
177
|
+
processingTimeMs,
|
|
178
|
+
},
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
/**
|
|
182
|
+
* Export drawing to SVG string
|
|
183
|
+
*/
|
|
184
|
+
exportSVG(drawing, options) {
|
|
185
|
+
return this.svgExporter.export(drawing, options);
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Generate hatching lines for cut polygons
|
|
189
|
+
*/
|
|
190
|
+
generateHatching(drawing) {
|
|
191
|
+
const hatchResults = this.hatchGenerator.generateHatches(drawing.cutPolygons, drawing.config.scale);
|
|
192
|
+
const hatchLines = [];
|
|
193
|
+
for (const result of hatchResults) {
|
|
194
|
+
for (const hatchLine of result.lines) {
|
|
195
|
+
hatchLines.push({
|
|
196
|
+
line: hatchLine.line,
|
|
197
|
+
category: 'annotation',
|
|
198
|
+
visibility: 'visible',
|
|
199
|
+
entityId: hatchLine.entityId,
|
|
200
|
+
ifcType: hatchLine.ifcType,
|
|
201
|
+
modelIndex: hatchLine.modelIndex,
|
|
202
|
+
depth: 0,
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
return hatchLines;
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Compute bounds from lines
|
|
210
|
+
*/
|
|
211
|
+
computeBounds(lines) {
|
|
212
|
+
let bounds = boundsEmpty();
|
|
213
|
+
for (const line of lines) {
|
|
214
|
+
bounds = boundsExtendLine(bounds, line.line);
|
|
215
|
+
}
|
|
216
|
+
return bounds;
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Dispose GPU resources
|
|
220
|
+
*/
|
|
221
|
+
dispose() {
|
|
222
|
+
if (this.gpuCutter) {
|
|
223
|
+
this.gpuCutter.destroy();
|
|
224
|
+
this.gpuCutter = null;
|
|
225
|
+
}
|
|
226
|
+
this.gpuDevice = null;
|
|
227
|
+
this.initialized = false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
231
|
+
// CONVENIENCE FUNCTIONS
|
|
232
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
233
|
+
/**
|
|
234
|
+
* Create a section configuration from simple parameters
|
|
235
|
+
*/
|
|
236
|
+
export function createSectionConfig(axis, position, options = {}) {
|
|
237
|
+
return {
|
|
238
|
+
plane: {
|
|
239
|
+
axis,
|
|
240
|
+
position,
|
|
241
|
+
flipped: false,
|
|
242
|
+
},
|
|
243
|
+
...DEFAULT_SECTION_CONFIG,
|
|
244
|
+
...options,
|
|
245
|
+
};
|
|
246
|
+
}
|
|
247
|
+
/**
|
|
248
|
+
* Quick helper to generate a floor plan
|
|
249
|
+
*/
|
|
250
|
+
export async function generateFloorPlan(meshes, elevation, options) {
|
|
251
|
+
const generator = new Drawing2DGenerator();
|
|
252
|
+
try {
|
|
253
|
+
await generator.initialize();
|
|
254
|
+
const config = createSectionConfig('y', elevation, {
|
|
255
|
+
projectionDepth: 3, // 3 meters below cut
|
|
256
|
+
scale: 100,
|
|
257
|
+
});
|
|
258
|
+
return await generator.generate(meshes, config, options);
|
|
259
|
+
}
|
|
260
|
+
finally {
|
|
261
|
+
generator.dispose();
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
/**
|
|
265
|
+
* Quick helper to generate a section
|
|
266
|
+
*/
|
|
267
|
+
export async function generateSection(meshes, axis, position, options) {
|
|
268
|
+
const generator = new Drawing2DGenerator();
|
|
269
|
+
try {
|
|
270
|
+
await generator.initialize();
|
|
271
|
+
const config = createSectionConfig(axis, position, {
|
|
272
|
+
projectionDepth: 10,
|
|
273
|
+
scale: 100,
|
|
274
|
+
});
|
|
275
|
+
return await generator.generate(meshes, config, options);
|
|
276
|
+
}
|
|
277
|
+
finally {
|
|
278
|
+
generator.dispose();
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
//# sourceMappingURL=drawing-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawing-generator.js","sourceRoot":"","sources":["../src/drawing-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Edge Extractor - Extract feature edges from triangle meshes
|
|
3
|
+
*
|
|
4
|
+
* Identifies:
|
|
5
|
+
* - Crease edges (sharp angles between adjacent faces)
|
|
6
|
+
* - Boundary edges (mesh borders)
|
|
7
|
+
* - Silhouette edges (contour edges for a given view direction)
|
|
8
|
+
*/
|
|
9
|
+
import type { MeshData } from '@ifc-lite/geometry';
|
|
10
|
+
import type { Vec3, EdgeData, DrawingLine, LineCategory } from './types';
|
|
11
|
+
export declare class EdgeExtractor {
|
|
12
|
+
/** Crease angle threshold in radians */
|
|
13
|
+
private creaseAngle;
|
|
14
|
+
constructor(creaseAngleDegrees?: number);
|
|
15
|
+
/**
|
|
16
|
+
* Extract all feature edges from a mesh
|
|
17
|
+
*/
|
|
18
|
+
extractEdges(mesh: MeshData): EdgeData[];
|
|
19
|
+
/**
|
|
20
|
+
* Extract edges from multiple meshes
|
|
21
|
+
*/
|
|
22
|
+
extractEdgesFromMeshes(meshes: MeshData[]): EdgeData[];
|
|
23
|
+
/**
|
|
24
|
+
* Extract silhouette edges for a given view direction
|
|
25
|
+
* Silhouette edges are where one adjacent face is front-facing and the other is back-facing
|
|
26
|
+
*/
|
|
27
|
+
extractSilhouettes(edges: EdgeData[], viewDirection: Vec3): EdgeData[];
|
|
28
|
+
/**
|
|
29
|
+
* Convert edges to 2D drawing lines
|
|
30
|
+
*/
|
|
31
|
+
edgesToDrawingLines(edges: EdgeData[], axis: 'x' | 'y' | 'z', flipped: boolean, category: LineCategory, sectionPosition: number): DrawingLine[];
|
|
32
|
+
/**
|
|
33
|
+
* Filter edges that are within a depth range from the section plane.
|
|
34
|
+
* Includes edges where:
|
|
35
|
+
* - Either endpoint is within range
|
|
36
|
+
* - The edge crosses through the depth band (one endpoint before, one after)
|
|
37
|
+
*/
|
|
38
|
+
filterEdgesByDepth(edges: EdgeData[], axis: 'x' | 'y' | 'z', sectionPosition: number, maxDepth: number, flipped: boolean): EdgeData[];
|
|
39
|
+
private getVertex;
|
|
40
|
+
private computeFaceNormal;
|
|
41
|
+
private registerEdge;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Get view direction from section axis
|
|
45
|
+
*/
|
|
46
|
+
export declare function getViewDirection(axis: 'x' | 'y' | 'z', flipped: boolean): Vec3;
|
|
47
|
+
//# sourceMappingURL=edge-extractor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-extractor.d.ts","sourceRoot":"","sources":["../src/edge-extractor.ts"],"names":[],"mappings":"AAIA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAW,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AA+BlF,qBAAa,aAAa;IACxB,wCAAwC;IACxC,OAAO,CAAC,WAAW,CAAS;gBAEhB,kBAAkB,GAAE,MAAW;IAI3C;;OAEG;IACH,YAAY,CAAC,IAAI,EAAE,QAAQ,GAAG,QAAQ,EAAE;IA+ExC;;OAEG;IACH,sBAAsB,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,QAAQ,EAAE;IAStD;;;OAGG;IACH,kBAAkB,CAAC,KAAK,EAAE,QAAQ,EAAE,EAAE,aAAa,EAAE,IAAI,GAAG,QAAQ,EAAE;IAsBtE;;OAEG;IACH,mBAAmB,CACjB,KAAK,EAAE,QAAQ,EAAE,EACjB,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EACrB,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,YAAY,EACtB,eAAe,EAAE,MAAM,GACtB,WAAW,EAAE;IAwBhB;;;;;OAKG;IACH,kBAAkB,CAChB,KAAK,EAAE,QAAQ,EAAE,EACjB,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EACrB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,GACf,QAAQ,EAAE;IA2Bb,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,iBAAiB;IAOzB,OAAO,CAAC,YAAY;CAoBrB;AAMD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,OAAO,EAAE,OAAO,GAAG,IAAI,CAU9E"}
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
|
+
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
|
+
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
+
import { vec3, vec3Sub, vec3Cross, vec3Normalize, vec3Dot, projectTo2D, } from './math';
|
|
5
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
6
|
+
// EDGE EXTRACTOR CLASS
|
|
7
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
8
|
+
export class EdgeExtractor {
|
|
9
|
+
/** Crease angle threshold in radians */
|
|
10
|
+
creaseAngle;
|
|
11
|
+
constructor(creaseAngleDegrees = 30) {
|
|
12
|
+
this.creaseAngle = (creaseAngleDegrees * Math.PI) / 180;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Extract all feature edges from a mesh
|
|
16
|
+
*/
|
|
17
|
+
extractEdges(mesh) {
|
|
18
|
+
const { positions, indices, expressId, ifcType, modelIndex } = mesh;
|
|
19
|
+
// Build edge-to-face adjacency map
|
|
20
|
+
const edgeMap = new Map();
|
|
21
|
+
const faceNormals = [];
|
|
22
|
+
const triangleCount = indices.length / 3;
|
|
23
|
+
// First pass: compute face normals and build edge adjacency
|
|
24
|
+
for (let t = 0; t < triangleCount; t++) {
|
|
25
|
+
const i0 = indices[t * 3];
|
|
26
|
+
const i1 = indices[t * 3 + 1];
|
|
27
|
+
const i2 = indices[t * 3 + 2];
|
|
28
|
+
// Get vertices
|
|
29
|
+
const v0 = this.getVertex(positions, i0);
|
|
30
|
+
const v1 = this.getVertex(positions, i1);
|
|
31
|
+
const v2 = this.getVertex(positions, i2);
|
|
32
|
+
// Compute face normal
|
|
33
|
+
const faceNormal = this.computeFaceNormal(v0, v1, v2);
|
|
34
|
+
faceNormals.push(faceNormal);
|
|
35
|
+
// Register edges
|
|
36
|
+
this.registerEdge(edgeMap, i0, i1, t);
|
|
37
|
+
this.registerEdge(edgeMap, i1, i2, t);
|
|
38
|
+
this.registerEdge(edgeMap, i2, i0, t);
|
|
39
|
+
}
|
|
40
|
+
// Second pass: classify edges
|
|
41
|
+
const edges = [];
|
|
42
|
+
for (const [, edgeInfo] of edgeMap) {
|
|
43
|
+
const v0 = this.getVertex(positions, edgeInfo.v0Idx);
|
|
44
|
+
const v1 = this.getVertex(positions, edgeInfo.v1Idx);
|
|
45
|
+
let face0Normal = null;
|
|
46
|
+
let face1Normal = null;
|
|
47
|
+
let dihedralAngle = 0;
|
|
48
|
+
let type = 'smooth';
|
|
49
|
+
if (edgeInfo.faceIndices.length === 1) {
|
|
50
|
+
// Boundary edge (only one adjacent face)
|
|
51
|
+
type = 'boundary';
|
|
52
|
+
face0Normal = faceNormals[edgeInfo.faceIndices[0]];
|
|
53
|
+
}
|
|
54
|
+
else if (edgeInfo.faceIndices.length >= 2) {
|
|
55
|
+
face0Normal = faceNormals[edgeInfo.faceIndices[0]];
|
|
56
|
+
face1Normal = faceNormals[edgeInfo.faceIndices[1]];
|
|
57
|
+
// Compute dihedral angle
|
|
58
|
+
const dot = Math.max(-1, Math.min(1, vec3Dot(face0Normal, face1Normal)));
|
|
59
|
+
dihedralAngle = Math.acos(dot);
|
|
60
|
+
// Classify as crease if angle exceeds threshold
|
|
61
|
+
if (dihedralAngle > this.creaseAngle) {
|
|
62
|
+
type = 'crease';
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Only include non-smooth edges
|
|
66
|
+
if (type !== 'smooth') {
|
|
67
|
+
edges.push({
|
|
68
|
+
v0,
|
|
69
|
+
v1,
|
|
70
|
+
face0Normal,
|
|
71
|
+
face1Normal,
|
|
72
|
+
dihedralAngle,
|
|
73
|
+
type,
|
|
74
|
+
entityId: expressId,
|
|
75
|
+
ifcType: ifcType || 'Unknown',
|
|
76
|
+
modelIndex: modelIndex || 0,
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return edges;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Extract edges from multiple meshes
|
|
84
|
+
*/
|
|
85
|
+
extractEdgesFromMeshes(meshes) {
|
|
86
|
+
const allEdges = [];
|
|
87
|
+
for (const mesh of meshes) {
|
|
88
|
+
const edges = this.extractEdges(mesh);
|
|
89
|
+
allEdges.push(...edges);
|
|
90
|
+
}
|
|
91
|
+
return allEdges;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Extract silhouette edges for a given view direction
|
|
95
|
+
* Silhouette edges are where one adjacent face is front-facing and the other is back-facing
|
|
96
|
+
*/
|
|
97
|
+
extractSilhouettes(edges, viewDirection) {
|
|
98
|
+
const normalizedView = vec3Normalize(viewDirection);
|
|
99
|
+
return edges.filter((edge) => {
|
|
100
|
+
// Boundary edges are always silhouettes
|
|
101
|
+
if (edge.type === 'boundary') {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
// Need both face normals for silhouette test
|
|
105
|
+
if (!edge.face0Normal || !edge.face1Normal) {
|
|
106
|
+
return false;
|
|
107
|
+
}
|
|
108
|
+
const dot0 = vec3Dot(edge.face0Normal, normalizedView);
|
|
109
|
+
const dot1 = vec3Dot(edge.face1Normal, normalizedView);
|
|
110
|
+
// Silhouette: one face toward viewer (dot < 0), one away (dot > 0)
|
|
111
|
+
return (dot0 < 0) !== (dot1 < 0);
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Convert edges to 2D drawing lines
|
|
116
|
+
*/
|
|
117
|
+
edgesToDrawingLines(edges, axis, flipped, category, sectionPosition) {
|
|
118
|
+
return edges.map((edge) => {
|
|
119
|
+
const start = projectTo2D(edge.v0, axis, flipped);
|
|
120
|
+
const end = projectTo2D(edge.v1, axis, flipped);
|
|
121
|
+
// Compute depth as distance from section plane
|
|
122
|
+
const depthAxis = axis;
|
|
123
|
+
const depth = Math.min(Math.abs(edge.v0[depthAxis] - sectionPosition), Math.abs(edge.v1[depthAxis] - sectionPosition));
|
|
124
|
+
return {
|
|
125
|
+
line: { start, end },
|
|
126
|
+
category,
|
|
127
|
+
visibility: 'visible',
|
|
128
|
+
entityId: edge.entityId,
|
|
129
|
+
ifcType: edge.ifcType,
|
|
130
|
+
modelIndex: edge.modelIndex,
|
|
131
|
+
depth,
|
|
132
|
+
};
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Filter edges that are within a depth range from the section plane.
|
|
137
|
+
* Includes edges where:
|
|
138
|
+
* - Either endpoint is within range
|
|
139
|
+
* - The edge crosses through the depth band (one endpoint before, one after)
|
|
140
|
+
*/
|
|
141
|
+
filterEdgesByDepth(edges, axis, sectionPosition, maxDepth, flipped) {
|
|
142
|
+
return edges.filter((edge) => {
|
|
143
|
+
const d0 = edge.v0[axis] - sectionPosition;
|
|
144
|
+
const d1 = edge.v1[axis] - sectionPosition;
|
|
145
|
+
// Define the valid depth range
|
|
146
|
+
// When not flipped: [0, maxDepth] (positive direction from plane)
|
|
147
|
+
// When flipped: [-maxDepth, 0] (negative direction from plane)
|
|
148
|
+
const rangeMin = flipped ? -maxDepth : 0;
|
|
149
|
+
const rangeMax = flipped ? 0 : maxDepth;
|
|
150
|
+
// Check if endpoints are within range
|
|
151
|
+
const inRange0 = d0 >= rangeMin && d0 <= rangeMax;
|
|
152
|
+
const inRange1 = d1 >= rangeMin && d1 <= rangeMax;
|
|
153
|
+
// Check if edge crosses the depth band
|
|
154
|
+
// This happens when one endpoint is before rangeMin and the other is after rangeMax
|
|
155
|
+
const crossesBand = (d0 < rangeMin && d1 > rangeMax) || (d1 < rangeMin && d0 > rangeMax);
|
|
156
|
+
return inRange0 || inRange1 || crossesBand;
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
160
|
+
// PRIVATE HELPERS
|
|
161
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
162
|
+
getVertex(positions, index) {
|
|
163
|
+
const base = index * 3;
|
|
164
|
+
return vec3(positions[base], positions[base + 1], positions[base + 2]);
|
|
165
|
+
}
|
|
166
|
+
computeFaceNormal(v0, v1, v2) {
|
|
167
|
+
const edge1 = vec3Sub(v1, v0);
|
|
168
|
+
const edge2 = vec3Sub(v2, v0);
|
|
169
|
+
const cross = vec3Cross(edge1, edge2);
|
|
170
|
+
return vec3Normalize(cross);
|
|
171
|
+
}
|
|
172
|
+
registerEdge(edgeMap, idx0, idx1, faceIndex) {
|
|
173
|
+
// Use canonical edge key (smaller index first)
|
|
174
|
+
const minIdx = Math.min(idx0, idx1);
|
|
175
|
+
const maxIdx = Math.max(idx0, idx1);
|
|
176
|
+
const key = `${minIdx}:${maxIdx}`;
|
|
177
|
+
if (!edgeMap.has(key)) {
|
|
178
|
+
edgeMap.set(key, {
|
|
179
|
+
v0Idx: minIdx,
|
|
180
|
+
v1Idx: maxIdx,
|
|
181
|
+
faceIndices: [],
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
edgeMap.get(key).faceIndices.push(faceIndex);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
188
|
+
// UTILITY FUNCTIONS
|
|
189
|
+
// ═══════════════════════════════════════════════════════════════════════════
|
|
190
|
+
/**
|
|
191
|
+
* Get view direction from section axis
|
|
192
|
+
*/
|
|
193
|
+
export function getViewDirection(axis, flipped) {
|
|
194
|
+
const sign = flipped ? 1 : -1;
|
|
195
|
+
switch (axis) {
|
|
196
|
+
case 'x':
|
|
197
|
+
return { x: sign, y: 0, z: 0 };
|
|
198
|
+
case 'y':
|
|
199
|
+
return { x: 0, y: sign, z: 0 };
|
|
200
|
+
case 'z':
|
|
201
|
+
return { x: 0, y: 0, z: sign };
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
//# sourceMappingURL=edge-extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-extractor.js","sourceRoot":"","sources":["../src/edge-extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* GPU Section Cutter - WebGPU compute shader for fast section cutting
|
|
3
|
+
*
|
|
4
|
+
* Accelerates triangle-plane intersection using parallel GPU computation.
|
|
5
|
+
* Falls back to CPU implementation when WebGPU is not available.
|
|
6
|
+
*/
|
|
7
|
+
import type { MeshData } from '@ifc-lite/geometry';
|
|
8
|
+
import type { CutSegment, SectionPlaneConfig } from './types';
|
|
9
|
+
export declare class GPUSectionCutter {
|
|
10
|
+
private device;
|
|
11
|
+
private resources;
|
|
12
|
+
constructor(device: GPUDevice);
|
|
13
|
+
/**
|
|
14
|
+
* Initialize GPU resources for a given maximum triangle count
|
|
15
|
+
*/
|
|
16
|
+
initialize(maxTriangles: number): Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* Cut meshes using GPU compute shader
|
|
19
|
+
*/
|
|
20
|
+
cutMeshes(meshes: MeshData[], config: SectionPlaneConfig): Promise<CutSegment[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Collect triangles from meshes into a flat buffer
|
|
23
|
+
*/
|
|
24
|
+
private collectTriangles;
|
|
25
|
+
/**
|
|
26
|
+
* Create plane uniform data
|
|
27
|
+
*/
|
|
28
|
+
private createPlaneData;
|
|
29
|
+
/**
|
|
30
|
+
* Parse GPU output into CutSegment array
|
|
31
|
+
*/
|
|
32
|
+
private parseSegments;
|
|
33
|
+
/**
|
|
34
|
+
* Release GPU resources
|
|
35
|
+
*/
|
|
36
|
+
destroy(): void;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Check if WebGPU compute shaders are available
|
|
40
|
+
*/
|
|
41
|
+
export declare function isGPUComputeAvailable(): boolean;
|
|
42
|
+
//# sourceMappingURL=gpu-section-cutter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gpu-section-cutter.d.ts","sourceRoot":"","sources":["../src/gpu-section-cutter.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAiB,MAAM,SAAS,CAAC;AAgK7E,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAY;IAC1B,OAAO,CAAC,SAAS,CAA6B;gBAElC,MAAM,EAAE,SAAS;IAI7B;;OAEG;IACG,UAAU,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAiFrD;;OAEG;IACG,SAAS,CACb,MAAM,EAAE,QAAQ,EAAE,EAClB,MAAM,EAAE,kBAAkB,GACzB,OAAO,CAAC,UAAU,EAAE,CAAC;IA2GxB;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAgExB;;OAEG;IACH,OAAO,CAAC,eAAe;IAsBvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkCrB;;OAEG;IACH,OAAO,IAAI,IAAI;CAWhB;AAMD;;GAEG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
|