@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.
Files changed (158) hide show
  1. package/LICENSE +373 -0
  2. package/dist/drawing-generator.d.ts +80 -0
  3. package/dist/drawing-generator.d.ts.map +1 -0
  4. package/dist/drawing-generator.js +281 -0
  5. package/dist/drawing-generator.js.map +1 -0
  6. package/dist/edge-extractor.d.ts +47 -0
  7. package/dist/edge-extractor.d.ts.map +1 -0
  8. package/dist/edge-extractor.js +204 -0
  9. package/dist/edge-extractor.js.map +1 -0
  10. package/dist/gpu-section-cutter.d.ts +42 -0
  11. package/dist/gpu-section-cutter.d.ts.map +1 -0
  12. package/dist/gpu-section-cutter.js +405 -0
  13. package/dist/gpu-section-cutter.js.map +1 -0
  14. package/dist/graphic-overrides/index.d.ts +10 -0
  15. package/dist/graphic-overrides/index.d.ts.map +1 -0
  16. package/dist/graphic-overrides/index.js +8 -0
  17. package/dist/graphic-overrides/index.js.map +1 -0
  18. package/dist/graphic-overrides/presets.d.ts +22 -0
  19. package/dist/graphic-overrides/presets.d.ts.map +1 -0
  20. package/dist/graphic-overrides/presets.js +283 -0
  21. package/dist/graphic-overrides/presets.js.map +1 -0
  22. package/dist/graphic-overrides/rule-engine.d.ts +64 -0
  23. package/dist/graphic-overrides/rule-engine.d.ts.map +1 -0
  24. package/dist/graphic-overrides/rule-engine.js +438 -0
  25. package/dist/graphic-overrides/rule-engine.js.map +1 -0
  26. package/dist/graphic-overrides/types.d.ts +200 -0
  27. package/dist/graphic-overrides/types.d.ts.map +1 -0
  28. package/dist/graphic-overrides/types.js +5 -0
  29. package/dist/graphic-overrides/types.js.map +1 -0
  30. package/dist/hatch-generator.d.ts +76 -0
  31. package/dist/hatch-generator.d.ts.map +1 -0
  32. package/dist/hatch-generator.js +282 -0
  33. package/dist/hatch-generator.js.map +1 -0
  34. package/dist/hidden-line.d.ts +64 -0
  35. package/dist/hidden-line.d.ts.map +1 -0
  36. package/dist/hidden-line.js +318 -0
  37. package/dist/hidden-line.js.map +1 -0
  38. package/dist/index.d.ts +44 -0
  39. package/dist/index.d.ts.map +1 -0
  40. package/dist/index.js +109 -0
  41. package/dist/index.js.map +1 -0
  42. package/dist/line-merger.d.ts +35 -0
  43. package/dist/line-merger.d.ts.map +1 -0
  44. package/dist/line-merger.js +265 -0
  45. package/dist/line-merger.js.map +1 -0
  46. package/dist/math.d.ts +90 -0
  47. package/dist/math.d.ts.map +1 -0
  48. package/dist/math.js +284 -0
  49. package/dist/math.js.map +1 -0
  50. package/dist/openings/index.d.ts +7 -0
  51. package/dist/openings/index.d.ts.map +1 -0
  52. package/dist/openings/index.js +10 -0
  53. package/dist/openings/index.js.map +1 -0
  54. package/dist/openings/opening-filter.d.ts +61 -0
  55. package/dist/openings/opening-filter.d.ts.map +1 -0
  56. package/dist/openings/opening-filter.js +244 -0
  57. package/dist/openings/opening-filter.js.map +1 -0
  58. package/dist/openings/opening-relationship-builder.d.ts +35 -0
  59. package/dist/openings/opening-relationship-builder.d.ts.map +1 -0
  60. package/dist/openings/opening-relationship-builder.js +121 -0
  61. package/dist/openings/opening-relationship-builder.js.map +1 -0
  62. package/dist/openings/opening-utils.d.ts +55 -0
  63. package/dist/openings/opening-utils.d.ts.map +1 -0
  64. package/dist/openings/opening-utils.js +128 -0
  65. package/dist/openings/opening-utils.js.map +1 -0
  66. package/dist/polygon-builder.d.ts +62 -0
  67. package/dist/polygon-builder.d.ts.map +1 -0
  68. package/dist/polygon-builder.js +261 -0
  69. package/dist/polygon-builder.js.map +1 -0
  70. package/dist/section-cutter.d.ts +49 -0
  71. package/dist/section-cutter.d.ts.map +1 -0
  72. package/dist/section-cutter.js +220 -0
  73. package/dist/section-cutter.js.map +1 -0
  74. package/dist/sheet/frame-renderer.d.ts +28 -0
  75. package/dist/sheet/frame-renderer.d.ts.map +1 -0
  76. package/dist/sheet/frame-renderer.js +199 -0
  77. package/dist/sheet/frame-renderer.js.map +1 -0
  78. package/dist/sheet/frame-types.d.ts +57 -0
  79. package/dist/sheet/frame-types.d.ts.map +1 -0
  80. package/dist/sheet/frame-types.js +88 -0
  81. package/dist/sheet/frame-types.js.map +1 -0
  82. package/dist/sheet/index.d.ts +26 -0
  83. package/dist/sheet/index.d.ts.map +1 -0
  84. package/dist/sheet/index.js +12 -0
  85. package/dist/sheet/index.js.map +1 -0
  86. package/dist/sheet/paper-sizes.d.ts +36 -0
  87. package/dist/sheet/paper-sizes.d.ts.map +1 -0
  88. package/dist/sheet/paper-sizes.js +252 -0
  89. package/dist/sheet/paper-sizes.js.map +1 -0
  90. package/dist/sheet/scale-bar-renderer.d.ts +29 -0
  91. package/dist/sheet/scale-bar-renderer.d.ts.map +1 -0
  92. package/dist/sheet/scale-bar-renderer.js +287 -0
  93. package/dist/sheet/scale-bar-renderer.js.map +1 -0
  94. package/dist/sheet/scale-bar-types.d.ts +82 -0
  95. package/dist/sheet/scale-bar-types.d.ts.map +1 -0
  96. package/dist/sheet/scale-bar-types.js +66 -0
  97. package/dist/sheet/scale-bar-types.js.map +1 -0
  98. package/dist/sheet/sheet-types.d.ts +84 -0
  99. package/dist/sheet/sheet-types.d.ts.map +1 -0
  100. package/dist/sheet/sheet-types.js +77 -0
  101. package/dist/sheet/sheet-types.js.map +1 -0
  102. package/dist/sheet/title-block-renderer.d.ts +44 -0
  103. package/dist/sheet/title-block-renderer.d.ts.map +1 -0
  104. package/dist/sheet/title-block-renderer.js +335 -0
  105. package/dist/sheet/title-block-renderer.js.map +1 -0
  106. package/dist/sheet/title-block-types.d.ts +100 -0
  107. package/dist/sheet/title-block-types.d.ts.map +1 -0
  108. package/dist/sheet/title-block-types.js +174 -0
  109. package/dist/sheet/title-block-types.js.map +1 -0
  110. package/dist/styles.d.ts +77 -0
  111. package/dist/styles.d.ts.map +1 -0
  112. package/dist/styles.js +347 -0
  113. package/dist/styles.js.map +1 -0
  114. package/dist/styling/index.d.ts +7 -0
  115. package/dist/styling/index.d.ts.map +1 -0
  116. package/dist/styling/index.js +10 -0
  117. package/dist/styling/index.js.map +1 -0
  118. package/dist/styling/layer-mapping.d.ts +57 -0
  119. package/dist/styling/layer-mapping.d.ts.map +1 -0
  120. package/dist/styling/layer-mapping.js +303 -0
  121. package/dist/styling/layer-mapping.js.map +1 -0
  122. package/dist/styling/line-styles.d.ts +49 -0
  123. package/dist/styling/line-styles.d.ts.map +1 -0
  124. package/dist/styling/line-styles.js +123 -0
  125. package/dist/styling/line-styles.js.map +1 -0
  126. package/dist/styling/line-weights.d.ts +61 -0
  127. package/dist/styling/line-weights.d.ts.map +1 -0
  128. package/dist/styling/line-weights.js +183 -0
  129. package/dist/styling/line-weights.js.map +1 -0
  130. package/dist/svg-exporter.d.ts +63 -0
  131. package/dist/svg-exporter.d.ts.map +1 -0
  132. package/dist/svg-exporter.js +278 -0
  133. package/dist/svg-exporter.js.map +1 -0
  134. package/dist/symbols/door-symbol.d.ts +82 -0
  135. package/dist/symbols/door-symbol.d.ts.map +1 -0
  136. package/dist/symbols/door-symbol.js +390 -0
  137. package/dist/symbols/door-symbol.js.map +1 -0
  138. package/dist/symbols/index.d.ts +8 -0
  139. package/dist/symbols/index.d.ts.map +1 -0
  140. package/dist/symbols/index.js +11 -0
  141. package/dist/symbols/index.js.map +1 -0
  142. package/dist/symbols/symbol-renderer.d.ts +29 -0
  143. package/dist/symbols/symbol-renderer.d.ts.map +1 -0
  144. package/dist/symbols/symbol-renderer.js +173 -0
  145. package/dist/symbols/symbol-renderer.js.map +1 -0
  146. package/dist/symbols/symbol-utils.d.ts +48 -0
  147. package/dist/symbols/symbol-utils.d.ts.map +1 -0
  148. package/dist/symbols/symbol-utils.js +129 -0
  149. package/dist/symbols/symbol-utils.js.map +1 -0
  150. package/dist/symbols/window-symbol.d.ts +57 -0
  151. package/dist/symbols/window-symbol.d.ts.map +1 -0
  152. package/dist/symbols/window-symbol.js +209 -0
  153. package/dist/symbols/window-symbol.js.map +1 -0
  154. package/dist/types.d.ts +443 -0
  155. package/dist/types.d.ts.map +1 -0
  156. package/dist/types.js +31 -0
  157. package/dist/types.js.map +1 -0
  158. package/package.json +53 -0
@@ -0,0 +1,128 @@
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 { OpeningRelationshipBuilder } from './opening-relationship-builder';
5
+ /**
6
+ * Build opening relationships from void and fill relationship arrays
7
+ */
8
+ export function buildOpeningRelationships(voids, fills, entityMetadata, modelIndex = 0) {
9
+ return new OpeningRelationshipBuilder(entityMetadata)
10
+ .addVoidRelationships(voids)
11
+ .addFillRelationships(fills)
12
+ .build(modelIndex);
13
+ }
14
+ /**
15
+ * Get all opening IDs for a host element (wall, slab, etc.)
16
+ */
17
+ export function getOpeningsForHost(relationships, hostId) {
18
+ return relationships.voidedBy.get(hostId) ?? [];
19
+ }
20
+ /**
21
+ * Get the filling element (door/window) for an opening
22
+ */
23
+ export function getFillingElement(relationships, openingId) {
24
+ return relationships.filledBy.get(openingId);
25
+ }
26
+ /**
27
+ * Get opening info by entity ID (works for both opening and filling elements)
28
+ */
29
+ export function getOpeningInfo(relationships, entityId) {
30
+ return relationships.openingInfo.get(entityId);
31
+ }
32
+ /**
33
+ * Check if an IFC type represents an opening element
34
+ */
35
+ export function isOpeningElement(ifcType) {
36
+ const upper = ifcType.toUpperCase();
37
+ return (upper === 'IFCOPENINGELEMENT' ||
38
+ upper === 'IFCOPENINGSTANDARDCASE' ||
39
+ upper === 'IFCVOIDINGELEMENT');
40
+ }
41
+ /**
42
+ * Check if an IFC type represents a door or window
43
+ */
44
+ export function isDoorOrWindow(ifcType) {
45
+ const upper = ifcType.toUpperCase();
46
+ return (upper.includes('DOOR') ||
47
+ upper.includes('WINDOW'));
48
+ }
49
+ /**
50
+ * Check if an IFC type is a host element that can have openings
51
+ */
52
+ export function isHostElement(ifcType) {
53
+ const upper = ifcType.toUpperCase();
54
+ return (upper.includes('WALL') ||
55
+ upper.includes('SLAB') ||
56
+ upper.includes('ROOF') ||
57
+ upper.includes('FLOOR'));
58
+ }
59
+ /**
60
+ * Get all host element IDs that have openings
61
+ */
62
+ export function getHostsWithOpenings(relationships) {
63
+ return Array.from(relationships.voidedBy.keys());
64
+ }
65
+ /**
66
+ * Get all door opening infos
67
+ */
68
+ export function getDoorOpenings(relationships) {
69
+ const result = [];
70
+ const seen = new Set();
71
+ for (const [, info] of relationships.openingInfo) {
72
+ if (info.type === 'door' && !seen.has(info.openingId)) {
73
+ result.push(info);
74
+ seen.add(info.openingId);
75
+ }
76
+ }
77
+ return result;
78
+ }
79
+ /**
80
+ * Get all window opening infos
81
+ */
82
+ export function getWindowOpenings(relationships) {
83
+ const result = [];
84
+ const seen = new Set();
85
+ for (const [, info] of relationships.openingInfo) {
86
+ if (info.type === 'window' && !seen.has(info.openingId)) {
87
+ result.push(info);
88
+ seen.add(info.openingId);
89
+ }
90
+ }
91
+ return result;
92
+ }
93
+ /**
94
+ * Filter entity IDs to exclude opening elements
95
+ * Useful for filtering meshes before section cutting
96
+ */
97
+ export function filterOutOpeningElements(entityIds, relationships) {
98
+ const openingIds = new Set();
99
+ // Collect all opening and filling element IDs
100
+ for (const openingIdList of relationships.voidedBy.values()) {
101
+ for (const id of openingIdList) {
102
+ openingIds.add(id);
103
+ }
104
+ }
105
+ for (const fillingId of relationships.filledBy.values()) {
106
+ openingIds.add(fillingId);
107
+ }
108
+ return entityIds.filter((id) => !openingIds.has(id));
109
+ }
110
+ /**
111
+ * Get the entity IDs that should be included in cut lines (hosts only)
112
+ * Excludes opening elements and their filling elements
113
+ */
114
+ export function getHostEntityIds(allEntityIds, relationships, ifcTypes) {
115
+ const result = [];
116
+ for (const id of allEntityIds) {
117
+ const ifcType = ifcTypes.get(id);
118
+ if (!ifcType)
119
+ continue;
120
+ // Skip opening elements and doors/windows
121
+ if (isOpeningElement(ifcType) || isDoorOrWindow(ifcType)) {
122
+ continue;
123
+ }
124
+ result.push(id);
125
+ }
126
+ return result;
127
+ }
128
+ //# sourceMappingURL=opening-utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"opening-utils.js","sourceRoot":"","sources":["../../src/openings/opening-utils.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Polygon Builder - Reconstructs closed polygons from cut line segments
3
+ *
4
+ * Takes the line segments from section cutting and connects them into
5
+ * closed polygon rings, handling:
6
+ * - Multiple disconnected polygons per entity
7
+ * - Holes (inner boundaries)
8
+ * - Floating point tolerance for vertex matching
9
+ */
10
+ import type { Point2D, CutSegment, DrawingPolygon } from './types';
11
+ export declare class PolygonBuilder {
12
+ /** Tolerance for vertex matching */
13
+ private tolerance;
14
+ constructor(tolerance?: number);
15
+ /**
16
+ * Build polygons from cut segments
17
+ * Groups segments by entity and reconstructs closed loops
18
+ */
19
+ buildPolygons(segments: CutSegment[]): DrawingPolygon[];
20
+ /**
21
+ * Build polygons for a single entity
22
+ */
23
+ private buildEntityPolygons;
24
+ /**
25
+ * Build closed loops from segments using a greedy chain-building algorithm
26
+ */
27
+ private buildLoops;
28
+ /**
29
+ * Build a single closed loop starting from a segment
30
+ */
31
+ private buildSingleLoop;
32
+ /**
33
+ * Find an unused segment that connects to the given point
34
+ */
35
+ private findConnectingSegment;
36
+ /**
37
+ * Classify loops as outer boundaries or holes
38
+ * Uses containment testing and area sign
39
+ */
40
+ private classifyLoops;
41
+ /**
42
+ * Check if a loop is contained within another loop
43
+ * Uses point-in-polygon test on the first point
44
+ */
45
+ private isLoopContainedIn;
46
+ /**
47
+ * Ray casting point-in-polygon test
48
+ */
49
+ private pointInPolygon;
50
+ }
51
+ /**
52
+ * Simplify polygon by removing collinear points
53
+ */
54
+ export declare function simplifyPolygon(points: Point2D[], tolerance?: number): Point2D[];
55
+ /**
56
+ * Compute polygon bounds
57
+ */
58
+ export declare function polygonBounds(points: Point2D[]): {
59
+ min: Point2D;
60
+ max: Point2D;
61
+ };
62
+ //# sourceMappingURL=polygon-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polygon-builder.d.ts","sourceRoot":"","sources":["../src/polygon-builder.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAa,UAAU,EAAE,cAAc,EAAa,MAAM,SAAS,CAAC;AA8BzF,qBAAa,cAAc;IACzB,oCAAoC;IACpC,OAAO,CAAC,SAAS,CAAS;gBAEd,SAAS,GAAE,MAAe;IAItC;;;OAGG;IACH,aAAa,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,cAAc,EAAE;IAuBvD;;OAEG;IACH,OAAO,CAAC,mBAAmB;IAkC3B;;OAEG;IACH,OAAO,CAAC,UAAU;IAmBlB;;OAEG;IACH,OAAO,CAAC,eAAe;IA8CvB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IA2B7B;;;OAGG;IACH,OAAO,CAAC,aAAa;IAwCrB;;;OAGG;IACH,OAAO,CAAC,iBAAiB;IAMzB;;OAEG;IACH,OAAO,CAAC,cAAc;CAkBvB;AAMD;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,OAAO,EAAE,EAAE,SAAS,GAAE,MAAc,GAAG,OAAO,EAAE,CAiBvF;AAWD;;GAEG;AACH,wBAAgB,aAAa,CAC3B,MAAM,EAAE,OAAO,EAAE,GAChB;IAAE,GAAG,EAAE,OAAO,CAAC;IAAC,GAAG,EAAE,OAAO,CAAA;CAAE,CAiBhC"}
@@ -0,0 +1,261 @@
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 { makeEntityKey } from './types';
5
+ import { point2DDistance, polygonSignedArea, ensureCCW, ensureCW, } from './math';
6
+ // ═══════════════════════════════════════════════════════════════════════════
7
+ // POLYGON BUILDER CLASS
8
+ // ═══════════════════════════════════════════════════════════════════════════
9
+ export class PolygonBuilder {
10
+ /** Tolerance for vertex matching */
11
+ tolerance;
12
+ constructor(tolerance = 0.0001) {
13
+ this.tolerance = tolerance;
14
+ }
15
+ /**
16
+ * Build polygons from cut segments
17
+ * Groups segments by entity and reconstructs closed loops
18
+ */
19
+ buildPolygons(segments) {
20
+ // Group segments by entity
21
+ const byEntity = new Map();
22
+ for (const seg of segments) {
23
+ const key = makeEntityKey(seg.modelIndex, seg.entityId);
24
+ if (!byEntity.has(key)) {
25
+ byEntity.set(key, []);
26
+ }
27
+ byEntity.get(key).push(seg);
28
+ }
29
+ // Build polygons for each entity - collect arrays for efficient flattening
30
+ const polygonArrays = [];
31
+ for (const [key, entitySegments] of byEntity) {
32
+ const entityPolygons = this.buildEntityPolygons(entitySegments);
33
+ polygonArrays.push(entityPolygons);
34
+ }
35
+ return polygonArrays.flat();
36
+ }
37
+ /**
38
+ * Build polygons for a single entity
39
+ */
40
+ buildEntityPolygons(segments) {
41
+ if (segments.length === 0)
42
+ return [];
43
+ const first = segments[0];
44
+ const { entityId, ifcType, modelIndex } = first;
45
+ // Convert to 2D segments
46
+ const segments2D = segments.map((seg) => ({
47
+ start: seg.p0_2d,
48
+ end: seg.p1_2d,
49
+ used: false,
50
+ }));
51
+ // Build closed loops
52
+ const loops = this.buildLoops(segments2D);
53
+ if (loops.length === 0)
54
+ return [];
55
+ // Classify loops as outer boundaries or holes
56
+ const classified = this.classifyLoops(loops);
57
+ // Build final polygons
58
+ return classified.map((c) => ({
59
+ polygon: {
60
+ outer: c.outer,
61
+ holes: c.holes,
62
+ },
63
+ entityId,
64
+ ifcType,
65
+ modelIndex,
66
+ isCut: true,
67
+ }));
68
+ }
69
+ /**
70
+ * Build closed loops from segments using a greedy chain-building algorithm
71
+ */
72
+ buildLoops(segments) {
73
+ const loops = [];
74
+ // Keep building loops until no more unused segments
75
+ while (true) {
76
+ // Find first unused segment
77
+ const startIdx = segments.findIndex((s) => !s.used);
78
+ if (startIdx === -1)
79
+ break;
80
+ const loop = this.buildSingleLoop(segments, startIdx);
81
+ if (loop && loop.length >= 3) {
82
+ const area = polygonSignedArea(loop);
83
+ loops.push({ points: loop, area });
84
+ }
85
+ }
86
+ return loops;
87
+ }
88
+ /**
89
+ * Build a single closed loop starting from a segment
90
+ */
91
+ buildSingleLoop(segments, startIdx) {
92
+ const points = [];
93
+ const startSeg = segments[startIdx];
94
+ startSeg.used = true;
95
+ points.push(startSeg.start);
96
+ let currentEnd = startSeg.end;
97
+ const loopStart = startSeg.start;
98
+ const maxIterations = segments.length;
99
+ let iterations = 0;
100
+ while (iterations < maxIterations) {
101
+ iterations++;
102
+ // Check if we've closed the loop
103
+ if (point2DDistance(currentEnd, loopStart) < this.tolerance) {
104
+ return points;
105
+ }
106
+ // Find next connecting segment
107
+ const nextIdx = this.findConnectingSegment(segments, currentEnd);
108
+ if (nextIdx === -1) {
109
+ // Can't close loop - mark remaining as unused and return partial
110
+ // This can happen with open geometry or numerical issues
111
+ break;
112
+ }
113
+ const nextSeg = segments[nextIdx];
114
+ nextSeg.used = true;
115
+ // Determine which end connects
116
+ if (point2DDistance(nextSeg.start, currentEnd) < this.tolerance) {
117
+ points.push(nextSeg.start);
118
+ currentEnd = nextSeg.end;
119
+ }
120
+ else {
121
+ points.push(nextSeg.end);
122
+ currentEnd = nextSeg.start;
123
+ }
124
+ }
125
+ // Loop didn't close - return points anyway for potential use
126
+ // Some entities may have open cross-sections
127
+ return points.length >= 3 ? points : null;
128
+ }
129
+ /**
130
+ * Find an unused segment that connects to the given point
131
+ */
132
+ findConnectingSegment(segments, point) {
133
+ let bestIdx = -1;
134
+ let bestDist = this.tolerance;
135
+ for (let i = 0; i < segments.length; i++) {
136
+ if (segments[i].used)
137
+ continue;
138
+ const seg = segments[i];
139
+ // Check start point
140
+ const distStart = point2DDistance(seg.start, point);
141
+ if (distStart < bestDist) {
142
+ bestDist = distStart;
143
+ bestIdx = i;
144
+ }
145
+ // Check end point
146
+ const distEnd = point2DDistance(seg.end, point);
147
+ if (distEnd < bestDist) {
148
+ bestDist = distEnd;
149
+ bestIdx = i;
150
+ }
151
+ }
152
+ return bestIdx;
153
+ }
154
+ /**
155
+ * Classify loops as outer boundaries or holes
156
+ * Uses containment testing and area sign
157
+ */
158
+ classifyLoops(loops) {
159
+ if (loops.length === 0)
160
+ return [];
161
+ // Sort by absolute area (largest first)
162
+ const sorted = [...loops].sort((a, b) => Math.abs(b.area) - Math.abs(a.area));
163
+ const result = [];
164
+ const assigned = new Set();
165
+ for (let i = 0; i < sorted.length; i++) {
166
+ if (assigned.has(i))
167
+ continue;
168
+ const outer = sorted[i];
169
+ // Ensure outer boundary is CCW
170
+ const outerPoints = ensureCCW(outer.points);
171
+ // Find holes (smaller loops contained within this one)
172
+ const holes = [];
173
+ for (let j = i + 1; j < sorted.length; j++) {
174
+ if (assigned.has(j))
175
+ continue;
176
+ const inner = sorted[j];
177
+ // Check if inner is contained in outer
178
+ if (this.isLoopContainedIn(inner.points, outerPoints)) {
179
+ // Ensure hole is CW (opposite winding)
180
+ holes.push(ensureCW(inner.points));
181
+ assigned.add(j);
182
+ }
183
+ }
184
+ assigned.add(i);
185
+ result.push({ outer: outerPoints, holes });
186
+ }
187
+ return result;
188
+ }
189
+ /**
190
+ * Check if a loop is contained within another loop
191
+ * Uses point-in-polygon test on the first point
192
+ */
193
+ isLoopContainedIn(inner, outer) {
194
+ // Test the first point of inner against outer
195
+ const testPoint = inner[0];
196
+ return this.pointInPolygon(testPoint, outer);
197
+ }
198
+ /**
199
+ * Ray casting point-in-polygon test
200
+ */
201
+ pointInPolygon(point, polygon) {
202
+ let inside = false;
203
+ const n = polygon.length;
204
+ for (let i = 0, j = n - 1; i < n; j = i++) {
205
+ const pi = polygon[i];
206
+ const pj = polygon[j];
207
+ if (pi.y > point.y !== pj.y > point.y &&
208
+ point.x < ((pj.x - pi.x) * (point.y - pi.y)) / (pj.y - pi.y) + pi.x) {
209
+ inside = !inside;
210
+ }
211
+ }
212
+ return inside;
213
+ }
214
+ }
215
+ // ═══════════════════════════════════════════════════════════════════════════
216
+ // HELPER FUNCTIONS
217
+ // ═══════════════════════════════════════════════════════════════════════════
218
+ /**
219
+ * Simplify polygon by removing collinear points
220
+ */
221
+ export function simplifyPolygon(points, tolerance = 0.001) {
222
+ if (points.length < 3)
223
+ return points;
224
+ const result = [];
225
+ for (let i = 0; i < points.length; i++) {
226
+ const prev = points[(i - 1 + points.length) % points.length];
227
+ const curr = points[i];
228
+ const next = points[(i + 1) % points.length];
229
+ // Check if current point is on the line between prev and next
230
+ if (!isCollinear(prev, curr, next, tolerance)) {
231
+ result.push(curr);
232
+ }
233
+ }
234
+ return result.length >= 3 ? result : points;
235
+ }
236
+ /**
237
+ * Check if three points are collinear
238
+ */
239
+ function isCollinear(a, b, c, tolerance) {
240
+ // Area of triangle formed by the three points
241
+ const area = Math.abs((b.x - a.x) * (c.y - a.y) - (c.x - a.x) * (b.y - a.y));
242
+ return area < tolerance;
243
+ }
244
+ /**
245
+ * Compute polygon bounds
246
+ */
247
+ export function polygonBounds(points) {
248
+ let minX = Infinity, minY = Infinity;
249
+ let maxX = -Infinity, maxY = -Infinity;
250
+ for (const p of points) {
251
+ minX = Math.min(minX, p.x);
252
+ minY = Math.min(minY, p.y);
253
+ maxX = Math.max(maxX, p.x);
254
+ maxY = Math.max(maxY, p.y);
255
+ }
256
+ return {
257
+ min: { x: minX, y: minY },
258
+ max: { x: maxX, y: maxY },
259
+ };
260
+ }
261
+ //# sourceMappingURL=polygon-builder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"polygon-builder.js","sourceRoot":"","sources":["../src/polygon-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Section Cutter - Core algorithm for cutting 3D triangle meshes with a plane
3
+ *
4
+ * Generates 2D line segments and reconstructed polygons for architectural drawings.
5
+ */
6
+ import type { MeshData } from '@ifc-lite/geometry';
7
+ import type { SectionPlaneConfig, CutSegment, MeshCutResult, SectionCutResult } from './types';
8
+ export declare class SectionCutter {
9
+ private planeNormal;
10
+ private planeDistance;
11
+ private axis;
12
+ private flipped;
13
+ constructor(config: SectionPlaneConfig);
14
+ /**
15
+ * Cut all meshes with the section plane
16
+ */
17
+ cutMeshes(meshes: MeshData[]): SectionCutResult;
18
+ /**
19
+ * Cut a single mesh with the section plane
20
+ */
21
+ cutSingleMesh(mesh: MeshData): MeshCutResult;
22
+ /**
23
+ * Get vertex from positions array
24
+ */
25
+ private getVertex;
26
+ /**
27
+ * Intersect a triangle with the section plane
28
+ * Returns the two intersection points, or null if no intersection
29
+ */
30
+ private intersectTrianglePlane;
31
+ /**
32
+ * Find intersection point of an edge with the plane
33
+ */
34
+ private edgePlaneIntersection;
35
+ }
36
+ export interface StreamingSectionCutterOptions {
37
+ /** Callback when a batch of segments is ready */
38
+ onSegments?: (segments: CutSegment[], progress: number) => void;
39
+ /** Batch size for streaming (number of meshes per batch) */
40
+ batchSize?: number;
41
+ /** Yield to event loop every N milliseconds */
42
+ yieldIntervalMs?: number;
43
+ }
44
+ /**
45
+ * Streaming section cutter for large models
46
+ * Processes meshes in batches to avoid blocking the main thread
47
+ */
48
+ export declare function cutMeshesStreaming(meshes: MeshData[], config: SectionPlaneConfig, options?: StreamingSectionCutterOptions): Promise<SectionCutResult>;
49
+ //# sourceMappingURL=section-cutter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"section-cutter.d.ts","sourceRoot":"","sources":["../src/section-cutter.ts"],"names":[],"mappings":"AAIA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,KAAK,EAGV,kBAAkB,EAClB,UAAU,EACV,aAAa,EACb,gBAAgB,EAGjB,MAAM,SAAS,CAAC;AAgBjB,qBAAa,aAAa;IACxB,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,OAAO,CAAU;gBAEb,MAAM,EAAE,kBAAkB;IAOtC;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,gBAAgB;IAqC/C;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,QAAQ,GAAG,aAAa;IA0D5C;;OAEG;IACH,OAAO,CAAC,SAAS;IAKjB;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IA6C9B;;OAEG;IACH,OAAO,CAAC,qBAAqB;CAwB9B;AAMD,MAAM,WAAW,6BAA6B;IAC5C,iDAAiD;IACjD,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,UAAU,EAAE,EAAE,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAChE,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,MAAM,EAAE,QAAQ,EAAE,EAClB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,6BAAkC,GAC1C,OAAO,CAAC,gBAAgB,CAAC,CA0D3B"}