@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,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hatch Generator - Generate hatch lines for cut polygons
|
|
3
|
+
*
|
|
4
|
+
* Creates parallel line patterns clipped to polygon boundaries
|
|
5
|
+
* for architectural section drawings.
|
|
6
|
+
*/
|
|
7
|
+
import type { Line2D, DrawingPolygon } from './types';
|
|
8
|
+
import type { HatchPattern, HatchPatternType } from './styles';
|
|
9
|
+
export interface HatchLine {
|
|
10
|
+
line: Line2D;
|
|
11
|
+
/** Source polygon entity ID */
|
|
12
|
+
entityId: number;
|
|
13
|
+
/** IFC type for styling */
|
|
14
|
+
ifcType: string;
|
|
15
|
+
/** Model index */
|
|
16
|
+
modelIndex: number;
|
|
17
|
+
}
|
|
18
|
+
export interface HatchResult {
|
|
19
|
+
/** Generated hatch lines */
|
|
20
|
+
lines: HatchLine[];
|
|
21
|
+
/** Pattern used */
|
|
22
|
+
pattern: HatchPattern;
|
|
23
|
+
/** Source polygon */
|
|
24
|
+
polygon: DrawingPolygon;
|
|
25
|
+
}
|
|
26
|
+
/** Custom hatch settings that can override IFC type-based patterns */
|
|
27
|
+
export interface CustomHatchSettings {
|
|
28
|
+
type: HatchPatternType;
|
|
29
|
+
spacing?: number;
|
|
30
|
+
angle?: number;
|
|
31
|
+
secondaryAngle?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class HatchGenerator {
|
|
34
|
+
/**
|
|
35
|
+
* Generate hatch lines for a polygon
|
|
36
|
+
* @param polygon The polygon to hatch
|
|
37
|
+
* @param scale Drawing scale (100 = 1:100)
|
|
38
|
+
* @param customSettings Optional override settings (type, spacing, angle)
|
|
39
|
+
*/
|
|
40
|
+
generateHatch(polygon: DrawingPolygon, scale?: number, customSettings?: CustomHatchSettings): HatchResult;
|
|
41
|
+
/**
|
|
42
|
+
* Generate hatching for multiple polygons
|
|
43
|
+
* @param polygons Polygons to hatch
|
|
44
|
+
* @param scale Drawing scale
|
|
45
|
+
* @param getCustomSettings Optional function to get custom settings per polygon
|
|
46
|
+
*/
|
|
47
|
+
generateHatches(polygons: DrawingPolygon[], scale?: number, getCustomSettings?: (polygon: DrawingPolygon) => CustomHatchSettings | undefined): HatchResult[];
|
|
48
|
+
/**
|
|
49
|
+
* Generate parallel lines at a given angle, clipped to polygon
|
|
50
|
+
*/
|
|
51
|
+
private generateParallelLines;
|
|
52
|
+
/**
|
|
53
|
+
* Clip a line to a polygon (with holes)
|
|
54
|
+
* Returns array of line segments inside the polygon
|
|
55
|
+
*/
|
|
56
|
+
private clipLineToPolygon;
|
|
57
|
+
/**
|
|
58
|
+
* Clip a line to a polygon ring
|
|
59
|
+
* @param inside If true, keep segments inside ring. If false, keep segments outside.
|
|
60
|
+
*/
|
|
61
|
+
private clipLineToRing;
|
|
62
|
+
/**
|
|
63
|
+
* Line-line intersection
|
|
64
|
+
* Returns t parameter on first line, or null if no intersection
|
|
65
|
+
*/
|
|
66
|
+
private lineLineIntersection;
|
|
67
|
+
/**
|
|
68
|
+
* Point in polygon ring test (ray casting)
|
|
69
|
+
*/
|
|
70
|
+
private pointInRing;
|
|
71
|
+
/**
|
|
72
|
+
* Compute bounding box of polygon
|
|
73
|
+
*/
|
|
74
|
+
private computePolygonBounds;
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=hatch-generator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hatch-generator.d.ts","sourceRoot":"","sources":["../src/hatch-generator.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAW,MAAM,EAAa,cAAc,EAAY,MAAM,SAAS,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAQ/D,MAAM,WAAW,SAAS;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,+BAA+B;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,2BAA2B;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,kBAAkB;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,WAAW;IAC1B,4BAA4B;IAC5B,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,mBAAmB;IACnB,OAAO,EAAE,YAAY,CAAC;IACtB,qBAAqB;IACrB,OAAO,EAAE,cAAc,CAAC;CACzB;AAMD,sEAAsE;AACtE,MAAM,WAAW,mBAAmB;IAClC,IAAI,EAAE,gBAAgB,CAAC;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,cAAc;IACzB;;;;;OAKG;IACH,aAAa,CACX,OAAO,EAAE,cAAc,EACvB,KAAK,GAAE,MAAY,EACnB,cAAc,CAAC,EAAE,mBAAmB,GACnC,WAAW;IA+Dd;;;;;OAKG;IACH,eAAe,CACb,QAAQ,EAAE,cAAc,EAAE,EAC1B,KAAK,GAAE,MAAY,EACnB,iBAAiB,CAAC,EAAE,CAAC,OAAO,EAAE,cAAc,KAAK,mBAAmB,GAAG,SAAS,GAC/E,WAAW,EAAE;IAOhB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgF7B;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAiBzB;;;OAGG;IACH,OAAO,CAAC,cAAc;IAqGtB;;;OAGG;IACH,OAAO,CAAC,oBAAoB;IA8B5B;;OAEG;IACH,OAAO,CAAC,WAAW;IAmBnB;;OAEG;IACH,OAAO,CAAC,oBAAoB;CAoB7B"}
|
|
@@ -0,0 +1,282 @@
|
|
|
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 { getHatchPattern } from './styles';
|
|
5
|
+
import { EPSILON } from './math';
|
|
6
|
+
export class HatchGenerator {
|
|
7
|
+
/**
|
|
8
|
+
* Generate hatch lines for a polygon
|
|
9
|
+
* @param polygon The polygon to hatch
|
|
10
|
+
* @param scale Drawing scale (100 = 1:100)
|
|
11
|
+
* @param customSettings Optional override settings (type, spacing, angle)
|
|
12
|
+
*/
|
|
13
|
+
generateHatch(polygon, scale = 100, customSettings) {
|
|
14
|
+
// Use custom settings if provided, otherwise lookup by IFC type
|
|
15
|
+
const basePattern = getHatchPattern(polygon.ifcType);
|
|
16
|
+
const pattern = customSettings
|
|
17
|
+
? {
|
|
18
|
+
...basePattern,
|
|
19
|
+
type: customSettings.type,
|
|
20
|
+
spacing: customSettings.spacing ?? basePattern.spacing,
|
|
21
|
+
angle: customSettings.angle ?? basePattern.angle,
|
|
22
|
+
secondaryAngle: customSettings.secondaryAngle ?? basePattern.secondaryAngle,
|
|
23
|
+
}
|
|
24
|
+
: basePattern;
|
|
25
|
+
if (pattern.type === 'none' || pattern.type === 'solid' || pattern.type === 'glass') {
|
|
26
|
+
return { lines: [], pattern, polygon };
|
|
27
|
+
}
|
|
28
|
+
// Adjust spacing for drawing scale
|
|
29
|
+
const spacing = pattern.spacing * (scale / 100);
|
|
30
|
+
let lines = [];
|
|
31
|
+
// Generate primary hatch direction
|
|
32
|
+
const primaryLines = this.generateParallelLines(polygon.polygon, spacing, pattern.angle, polygon.entityId, polygon.ifcType, polygon.modelIndex);
|
|
33
|
+
lines.push(...primaryLines);
|
|
34
|
+
// Generate secondary direction for cross-hatch
|
|
35
|
+
if (pattern.type === 'cross-hatch' && pattern.secondaryAngle !== undefined) {
|
|
36
|
+
const secondaryLines = this.generateParallelLines(polygon.polygon, spacing, pattern.secondaryAngle, polygon.entityId, polygon.ifcType, polygon.modelIndex);
|
|
37
|
+
lines.push(...secondaryLines);
|
|
38
|
+
}
|
|
39
|
+
// Special patterns
|
|
40
|
+
if (pattern.type === 'concrete') {
|
|
41
|
+
// Concrete uses random dots - we'll approximate with offset diagonal lines
|
|
42
|
+
const offsetLines = this.generateParallelLines(polygon.polygon, spacing * 1.5, pattern.angle + 90, polygon.entityId, polygon.ifcType, polygon.modelIndex);
|
|
43
|
+
lines.push(...offsetLines);
|
|
44
|
+
}
|
|
45
|
+
return { lines, pattern, polygon };
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Generate hatching for multiple polygons
|
|
49
|
+
* @param polygons Polygons to hatch
|
|
50
|
+
* @param scale Drawing scale
|
|
51
|
+
* @param getCustomSettings Optional function to get custom settings per polygon
|
|
52
|
+
*/
|
|
53
|
+
generateHatches(polygons, scale = 100, getCustomSettings) {
|
|
54
|
+
return polygons.map((polygon) => {
|
|
55
|
+
const customSettings = getCustomSettings?.(polygon);
|
|
56
|
+
return this.generateHatch(polygon, scale, customSettings);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Generate parallel lines at a given angle, clipped to polygon
|
|
61
|
+
*/
|
|
62
|
+
generateParallelLines(polygon, spacing, angleDegrees, entityId, ifcType, modelIndex) {
|
|
63
|
+
if (spacing < EPSILON)
|
|
64
|
+
return [];
|
|
65
|
+
const angleRad = (angleDegrees * Math.PI) / 180;
|
|
66
|
+
// Direction perpendicular to hatch lines (for stepping)
|
|
67
|
+
const perpX = Math.cos(angleRad);
|
|
68
|
+
const perpY = Math.sin(angleRad);
|
|
69
|
+
// Direction along hatch lines
|
|
70
|
+
const alongX = -perpY;
|
|
71
|
+
const alongY = perpX;
|
|
72
|
+
// Compute bounds of polygon
|
|
73
|
+
const bounds = this.computePolygonBounds(polygon);
|
|
74
|
+
if (!bounds)
|
|
75
|
+
return [];
|
|
76
|
+
// Project corners onto perpendicular direction to find range
|
|
77
|
+
const corners = [
|
|
78
|
+
{ x: bounds.min.x, y: bounds.min.y },
|
|
79
|
+
{ x: bounds.max.x, y: bounds.min.y },
|
|
80
|
+
{ x: bounds.max.x, y: bounds.max.y },
|
|
81
|
+
{ x: bounds.min.x, y: bounds.max.y },
|
|
82
|
+
];
|
|
83
|
+
let minD = Infinity;
|
|
84
|
+
let maxD = -Infinity;
|
|
85
|
+
for (const c of corners) {
|
|
86
|
+
const d = c.x * perpX + c.y * perpY;
|
|
87
|
+
minD = Math.min(minD, d);
|
|
88
|
+
maxD = Math.max(maxD, d);
|
|
89
|
+
}
|
|
90
|
+
// Extent for lines (diagonal of bounds)
|
|
91
|
+
const extent = Math.sqrt(Math.pow(bounds.max.x - bounds.min.x, 2) + Math.pow(bounds.max.y - bounds.min.y, 2)) * 1.5;
|
|
92
|
+
const lines = [];
|
|
93
|
+
// Generate lines at regular intervals
|
|
94
|
+
for (let d = minD; d <= maxD; d += spacing) {
|
|
95
|
+
// Point on the perpendicular at distance d
|
|
96
|
+
const originX = d * perpX;
|
|
97
|
+
const originY = d * perpY;
|
|
98
|
+
// Line endpoints extending in both directions
|
|
99
|
+
const lineStart = {
|
|
100
|
+
x: originX - alongX * extent,
|
|
101
|
+
y: originY - alongY * extent,
|
|
102
|
+
};
|
|
103
|
+
const lineEnd = {
|
|
104
|
+
x: originX + alongX * extent,
|
|
105
|
+
y: originY + alongY * extent,
|
|
106
|
+
};
|
|
107
|
+
// Clip line against polygon
|
|
108
|
+
const clippedSegments = this.clipLineToPolygon({ start: lineStart, end: lineEnd }, polygon);
|
|
109
|
+
for (const segment of clippedSegments) {
|
|
110
|
+
lines.push({
|
|
111
|
+
line: segment,
|
|
112
|
+
entityId,
|
|
113
|
+
ifcType,
|
|
114
|
+
modelIndex,
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return lines;
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Clip a line to a polygon (with holes)
|
|
122
|
+
* Returns array of line segments inside the polygon
|
|
123
|
+
*/
|
|
124
|
+
clipLineToPolygon(line, polygon) {
|
|
125
|
+
// First clip to outer boundary
|
|
126
|
+
let segments = this.clipLineToRing(line, polygon.outer, true);
|
|
127
|
+
// Then subtract holes
|
|
128
|
+
for (const hole of polygon.holes) {
|
|
129
|
+
const newSegments = [];
|
|
130
|
+
for (const segment of segments) {
|
|
131
|
+
const clipped = this.clipLineToRing(segment, hole, false);
|
|
132
|
+
newSegments.push(...clipped);
|
|
133
|
+
}
|
|
134
|
+
segments = newSegments;
|
|
135
|
+
}
|
|
136
|
+
return segments;
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Clip a line to a polygon ring
|
|
140
|
+
* @param inside If true, keep segments inside ring. If false, keep segments outside.
|
|
141
|
+
*/
|
|
142
|
+
clipLineToRing(line, ring, inside) {
|
|
143
|
+
// Find all intersections with ring edges
|
|
144
|
+
const intersections = [];
|
|
145
|
+
const dx = line.end.x - line.start.x;
|
|
146
|
+
const dy = line.end.y - line.start.y;
|
|
147
|
+
for (let i = 0; i < ring.length; i++) {
|
|
148
|
+
const j = (i + 1) % ring.length;
|
|
149
|
+
const p1 = ring[i];
|
|
150
|
+
const p2 = ring[j];
|
|
151
|
+
const intersection = this.lineLineIntersection(line.start, line.end, p1, p2);
|
|
152
|
+
if (intersection !== null && intersection.t >= 0 && intersection.t <= 1) {
|
|
153
|
+
// Determine if entering or leaving the polygon
|
|
154
|
+
// Using edge normal direction
|
|
155
|
+
const edgeNormalX = -(p2.y - p1.y);
|
|
156
|
+
const edgeNormalY = p2.x - p1.x;
|
|
157
|
+
const entering = dx * edgeNormalX + dy * edgeNormalY > 0;
|
|
158
|
+
intersections.push({ t: intersection.t, entering });
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
// Sort by t parameter
|
|
162
|
+
intersections.sort((a, b) => a.t - b.t);
|
|
163
|
+
// Remove duplicate intersections (at same t)
|
|
164
|
+
const uniqueIntersections = [];
|
|
165
|
+
for (const int of intersections) {
|
|
166
|
+
if (uniqueIntersections.length === 0 ||
|
|
167
|
+
Math.abs(int.t - uniqueIntersections[uniqueIntersections.length - 1].t) > EPSILON) {
|
|
168
|
+
uniqueIntersections.push(int);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (uniqueIntersections.length === 0) {
|
|
172
|
+
// No intersections - line is either entirely inside or outside
|
|
173
|
+
const midpoint = {
|
|
174
|
+
x: (line.start.x + line.end.x) / 2,
|
|
175
|
+
y: (line.start.y + line.end.y) / 2,
|
|
176
|
+
};
|
|
177
|
+
const isInside = this.pointInRing(midpoint, ring);
|
|
178
|
+
if (isInside === inside) {
|
|
179
|
+
return [line];
|
|
180
|
+
}
|
|
181
|
+
return [];
|
|
182
|
+
}
|
|
183
|
+
// Build segments based on intersections
|
|
184
|
+
const segments = [];
|
|
185
|
+
// Check if we start inside
|
|
186
|
+
let currentlyInside = this.pointInRing(line.start, ring);
|
|
187
|
+
let lastT = 0;
|
|
188
|
+
for (const int of uniqueIntersections) {
|
|
189
|
+
if (currentlyInside === inside) {
|
|
190
|
+
// Add segment from lastT to this intersection
|
|
191
|
+
segments.push({
|
|
192
|
+
start: {
|
|
193
|
+
x: line.start.x + lastT * dx,
|
|
194
|
+
y: line.start.y + lastT * dy,
|
|
195
|
+
},
|
|
196
|
+
end: {
|
|
197
|
+
x: line.start.x + int.t * dx,
|
|
198
|
+
y: line.start.y + int.t * dy,
|
|
199
|
+
},
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
lastT = int.t;
|
|
203
|
+
currentlyInside = !currentlyInside;
|
|
204
|
+
}
|
|
205
|
+
// Handle final segment to end
|
|
206
|
+
if (currentlyInside === inside) {
|
|
207
|
+
segments.push({
|
|
208
|
+
start: {
|
|
209
|
+
x: line.start.x + lastT * dx,
|
|
210
|
+
y: line.start.y + lastT * dy,
|
|
211
|
+
},
|
|
212
|
+
end: line.end,
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
// Filter out degenerate segments
|
|
216
|
+
return segments.filter((seg) => {
|
|
217
|
+
const len = Math.abs(seg.end.x - seg.start.x) + Math.abs(seg.end.y - seg.start.y);
|
|
218
|
+
return len > EPSILON;
|
|
219
|
+
});
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Line-line intersection
|
|
223
|
+
* Returns t parameter on first line, or null if no intersection
|
|
224
|
+
*/
|
|
225
|
+
lineLineIntersection(p1, p2, p3, p4) {
|
|
226
|
+
const d1x = p2.x - p1.x;
|
|
227
|
+
const d1y = p2.y - p1.y;
|
|
228
|
+
const d2x = p4.x - p3.x;
|
|
229
|
+
const d2y = p4.y - p3.y;
|
|
230
|
+
const cross = d1x * d2y - d1y * d2x;
|
|
231
|
+
if (Math.abs(cross) < EPSILON) {
|
|
232
|
+
return null; // Parallel
|
|
233
|
+
}
|
|
234
|
+
const dx = p3.x - p1.x;
|
|
235
|
+
const dy = p3.y - p1.y;
|
|
236
|
+
const t = (dx * d2y - dy * d2x) / cross;
|
|
237
|
+
const u = (dx * d1y - dy * d1x) / cross;
|
|
238
|
+
// Check if intersection is within edge segment
|
|
239
|
+
if (u < 0 || u > 1) {
|
|
240
|
+
return null;
|
|
241
|
+
}
|
|
242
|
+
return { t, u };
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Point in polygon ring test (ray casting)
|
|
246
|
+
*/
|
|
247
|
+
pointInRing(point, ring) {
|
|
248
|
+
let inside = false;
|
|
249
|
+
const n = ring.length;
|
|
250
|
+
for (let i = 0, j = n - 1; i < n; j = i++) {
|
|
251
|
+
const pi = ring[i];
|
|
252
|
+
const pj = ring[j];
|
|
253
|
+
if (pi.y > point.y !== pj.y > point.y &&
|
|
254
|
+
point.x < ((pj.x - pi.x) * (point.y - pi.y)) / (pj.y - pi.y) + pi.x) {
|
|
255
|
+
inside = !inside;
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
return inside;
|
|
259
|
+
}
|
|
260
|
+
/**
|
|
261
|
+
* Compute bounding box of polygon
|
|
262
|
+
*/
|
|
263
|
+
computePolygonBounds(polygon) {
|
|
264
|
+
if (polygon.outer.length === 0)
|
|
265
|
+
return null;
|
|
266
|
+
let minX = Infinity;
|
|
267
|
+
let minY = Infinity;
|
|
268
|
+
let maxX = -Infinity;
|
|
269
|
+
let maxY = -Infinity;
|
|
270
|
+
for (const p of polygon.outer) {
|
|
271
|
+
minX = Math.min(minX, p.x);
|
|
272
|
+
minY = Math.min(minY, p.y);
|
|
273
|
+
maxX = Math.max(maxX, p.x);
|
|
274
|
+
maxY = Math.max(maxY, p.y);
|
|
275
|
+
}
|
|
276
|
+
return {
|
|
277
|
+
min: { x: minX, y: minY },
|
|
278
|
+
max: { x: maxX, y: maxY },
|
|
279
|
+
};
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
//# sourceMappingURL=hatch-generator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hatch-generator.js","sourceRoot":"","sources":["../src/hatch-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Hidden Line Classifier - Determine visibility of lines via depth testing
|
|
3
|
+
*
|
|
4
|
+
* Uses software rasterization to build a depth buffer, then classifies
|
|
5
|
+
* each line segment as visible, hidden, or partially visible.
|
|
6
|
+
*/
|
|
7
|
+
import type { MeshData } from '@ifc-lite/geometry';
|
|
8
|
+
import type { Point2D, DrawingLine, Bounds2D, VisibilityState } from './types';
|
|
9
|
+
export interface VisibilitySegment {
|
|
10
|
+
start: Point2D;
|
|
11
|
+
end: Point2D;
|
|
12
|
+
visible: boolean;
|
|
13
|
+
}
|
|
14
|
+
export interface VisibilityResult {
|
|
15
|
+
line: DrawingLine;
|
|
16
|
+
segments: VisibilitySegment[];
|
|
17
|
+
overallVisibility: VisibilityState;
|
|
18
|
+
}
|
|
19
|
+
export interface HiddenLineOptions {
|
|
20
|
+
/** Resolution of depth buffer (pixels on longest axis) */
|
|
21
|
+
resolution: number;
|
|
22
|
+
/** Number of samples along each line for visibility testing */
|
|
23
|
+
samplesPerLine: number;
|
|
24
|
+
/** Depth bias to avoid z-fighting */
|
|
25
|
+
depthBias: number;
|
|
26
|
+
}
|
|
27
|
+
export declare class HiddenLineClassifier {
|
|
28
|
+
private options;
|
|
29
|
+
private depthBuffer;
|
|
30
|
+
private width;
|
|
31
|
+
private height;
|
|
32
|
+
private bounds;
|
|
33
|
+
constructor(options?: Partial<HiddenLineOptions>);
|
|
34
|
+
/**
|
|
35
|
+
* Build depth buffer from projected triangles
|
|
36
|
+
*
|
|
37
|
+
* @param meshes Source meshes
|
|
38
|
+
* @param axis Section axis
|
|
39
|
+
* @param sectionPosition Position along axis
|
|
40
|
+
* @param maxDepth Maximum depth to render
|
|
41
|
+
* @param flipped Whether view is flipped
|
|
42
|
+
* @param bounds Optional pre-computed 2D bounds
|
|
43
|
+
*/
|
|
44
|
+
buildDepthBuffer(meshes: MeshData[], axis: 'x' | 'y' | 'z', sectionPosition: number, maxDepth: number, flipped: boolean, bounds?: Bounds2D): void;
|
|
45
|
+
/**
|
|
46
|
+
* Classify lines as visible or hidden based on depth buffer
|
|
47
|
+
*/
|
|
48
|
+
classifyLines(lines: DrawingLine[]): VisibilityResult[];
|
|
49
|
+
/**
|
|
50
|
+
* Update lines with visibility classification
|
|
51
|
+
* Returns new array with visibility set
|
|
52
|
+
*/
|
|
53
|
+
applyVisibility(lines: DrawingLine[]): DrawingLine[];
|
|
54
|
+
private computeBounds;
|
|
55
|
+
private getProjectionAxes;
|
|
56
|
+
private rasterizeMesh;
|
|
57
|
+
private getVertex;
|
|
58
|
+
private projectVertex;
|
|
59
|
+
private rasterizeTriangle;
|
|
60
|
+
private barycentricCoords;
|
|
61
|
+
private classifySingleLine;
|
|
62
|
+
private sampleVisibility;
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=hidden-line.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hidden-line.d.ts","sourceRoot":"","sources":["../src/hidden-line.ts"],"names":[],"mappings":"AAIA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAAQ,OAAO,EAAU,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAc7F,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,OAAO,CAAC;IACf,GAAG,EAAE,OAAO,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,WAAW,CAAC;IAClB,QAAQ,EAAE,iBAAiB,EAAE,CAAC;IAC9B,iBAAiB,EAAE,eAAe,CAAC;CACpC;AAED,MAAM,WAAW,iBAAiB;IAChC,0DAA0D;IAC1D,UAAU,EAAE,MAAM,CAAC;IACnB,+DAA+D;IAC/D,cAAc,EAAE,MAAM,CAAC;IACvB,qCAAqC;IACrC,SAAS,EAAE,MAAM,CAAC;CACnB;AAYD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,OAAO,CAAoB;IAEnC,OAAO,CAAC,WAAW,CAA6B;IAChD,OAAO,CAAC,KAAK,CAAa;IAC1B,OAAO,CAAC,MAAM,CAAa;IAC3B,OAAO,CAAC,MAAM,CAAyB;gBAE3B,OAAO,GAAE,OAAO,CAAC,iBAAiB,CAAM;IAIpD;;;;;;;;;OASG;IACH,gBAAgB,CACd,MAAM,EAAE,QAAQ,EAAE,EAClB,IAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EACrB,eAAe,EAAE,MAAM,EACvB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,OAAO,EAChB,MAAM,CAAC,EAAE,QAAQ,GAChB,IAAI;IAqCP;;OAEG;IACH,aAAa,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,gBAAgB,EAAE;IAevD;;;OAGG;IACH,eAAe,CAAC,KAAK,EAAE,WAAW,EAAE,GAAG,WAAW,EAAE;IA6BpD,OAAO,CAAC,aAAa;IA6CrB,OAAO,CAAC,iBAAiB;IAWzB,OAAO,CAAC,aAAa;IA4CrB,OAAO,CAAC,SAAS;IAKjB,OAAO,CAAC,aAAa;IAiBrB,OAAO,CAAC,iBAAiB;IAyCzB,OAAO,CAAC,iBAAiB;IAiCzB,OAAO,CAAC,kBAAkB;IAgE1B,OAAO,CAAC,gBAAgB;CAoBzB"}
|