@ifc-lite/ifcx 1.2.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.
@@ -0,0 +1,104 @@
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 { ATTR, BUILDING_ELEMENT_TYPES } from './types.js';
5
+ import { EntityTableBuilder, } from '@ifc-lite/data';
6
+ /**
7
+ * Extract entities from composed IFCX nodes.
8
+ *
9
+ * Mapping:
10
+ * - path -> expressId (synthetic, auto-incrementing)
11
+ * - bsi::ifc::class.code -> typeEnum
12
+ * - children hierarchy -> spatial structure
13
+ */
14
+ export function extractEntities(composed, strings) {
15
+ const pathToId = new Map();
16
+ const idToPath = new Map();
17
+ // First pass: count entities to allocate builder
18
+ let entityCount = 0;
19
+ for (const node of composed.values()) {
20
+ const ifcClass = node.attributes.get(ATTR.CLASS);
21
+ if (ifcClass) {
22
+ entityCount++;
23
+ }
24
+ }
25
+ const builder = new EntityTableBuilder(Math.max(entityCount, 100), strings);
26
+ let nextExpressId = 1;
27
+ // Second pass: extract entities
28
+ for (const node of composed.values()) {
29
+ const ifcClass = node.attributes.get(ATTR.CLASS);
30
+ if (!ifcClass)
31
+ continue; // Skip non-IFC nodes (geometry-only, materials, etc.)
32
+ const expressId = nextExpressId++;
33
+ pathToId.set(node.path, expressId);
34
+ idToPath.set(expressId, node.path);
35
+ // Extract name from attributes
36
+ const name = extractName(node) ?? node.path.slice(0, 8);
37
+ // Check if has geometry
38
+ const hasGeometry = hasGeometryInSubtree(node);
39
+ // Check if this is a type definition
40
+ const isType = ifcClass.code.toUpperCase().endsWith('TYPE');
41
+ // Add entity to builder
42
+ builder.add(expressId, ifcClass.code, node.path, // Use path as GlobalId
43
+ name, '', // description
44
+ ifcClass.code, // objectType
45
+ hasGeometry, isType);
46
+ }
47
+ return {
48
+ entities: builder.build(),
49
+ pathToId,
50
+ idToPath,
51
+ };
52
+ }
53
+ /**
54
+ * Extract entity name from node attributes.
55
+ */
56
+ function extractName(node) {
57
+ // Try common property patterns
58
+ const name = node.attributes.get('bsi::ifc::prop::Name');
59
+ if (typeof name === 'string')
60
+ return name;
61
+ const typeName = node.attributes.get('bsi::ifc::prop::TypeName');
62
+ if (typeof typeName === 'string')
63
+ return typeName;
64
+ const objectName = node.attributes.get('bsi::ifc::prop::ObjectName');
65
+ if (typeof objectName === 'string')
66
+ return objectName;
67
+ // Try to get name from the node's child key in parent
68
+ // (e.g., if parent has children: { "Wall_001": path }, use "Wall_001")
69
+ const parent = node.parent;
70
+ if (parent) {
71
+ for (const [key, child] of parent.children) {
72
+ if (child.path === node.path) {
73
+ // Use the child key as name if it's not just the path
74
+ if (key !== node.path && !key.match(/^[0-9a-f-]{36}$/i)) {
75
+ return key;
76
+ }
77
+ }
78
+ }
79
+ }
80
+ return null;
81
+ }
82
+ /**
83
+ * Check if node or any of its children have geometry.
84
+ */
85
+ function hasGeometryInSubtree(node) {
86
+ // Check this node
87
+ if (node.attributes.has(ATTR.MESH)) {
88
+ return true;
89
+ }
90
+ // Check children
91
+ for (const child of node.children.values()) {
92
+ if (hasGeometryInSubtree(child)) {
93
+ return true;
94
+ }
95
+ }
96
+ return false;
97
+ }
98
+ /**
99
+ * Check if a type code represents a building element.
100
+ */
101
+ export function isBuildingElement(typeCode) {
102
+ return BUILDING_ELEMENT_TYPES.has(typeCode);
103
+ }
104
+ //# sourceMappingURL=entity-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"entity-extractor.js","sourceRoot":"","sources":["../src/entity-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Geometry Extractor for IFCX
3
+ * Extracts USD-style mesh data and converts to MeshData format
4
+ *
5
+ * COORDINATE SYSTEM:
6
+ * - IFCX uses Z-up (following IFC/buildingSMART convention)
7
+ * - The ifc-lite viewer uses Y-up (standard WebGL convention)
8
+ * - This extractor converts from Z-up to Y-up after applying transforms
9
+ */
10
+ import type { ComposedNode } from './types.js';
11
+ /**
12
+ * MeshData interface compatible with @ifc-lite/geometry
13
+ */
14
+ export interface MeshData {
15
+ expressId: number;
16
+ ifcType?: string;
17
+ positions: Float32Array;
18
+ normals: Float32Array;
19
+ indices: Uint32Array;
20
+ color: [number, number, number, number];
21
+ }
22
+ /**
23
+ * Extract geometry from composed IFCX nodes.
24
+ *
25
+ * IFC5 geometry is pre-tessellated (unlike IFC4 parametric geometry),
26
+ * so this is straightforward mesh extraction.
27
+ *
28
+ * Note: Meshes are often on child nodes (like "Body", "Axis") that don't
29
+ * have their own bsi::ifc::class. We associate these with the closest
30
+ * ancestor entity that has an expressId.
31
+ *
32
+ * Output geometry is converted to Y-up for the viewer.
33
+ */
34
+ export declare function extractGeometry(composed: Map<string, ComposedNode>, pathToId: Map<string, number>): MeshData[];
35
+ //# sourceMappingURL=geometry-extractor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry-extractor.d.ts","sourceRoot":"","sources":["../src/geometry-extractor.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAyB,MAAM,YAAY,CAAC;AAGtE;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,YAAY,CAAC;IACxB,OAAO,EAAE,YAAY,CAAC;IACtB,OAAO,EAAE,WAAW,CAAC;IACrB,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;CACzC;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,CAC7B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,QAAQ,EAAE,CA2BZ"}
@@ -0,0 +1,301 @@
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 { ATTR } from './types.js';
5
+ /**
6
+ * Extract geometry from composed IFCX nodes.
7
+ *
8
+ * IFC5 geometry is pre-tessellated (unlike IFC4 parametric geometry),
9
+ * so this is straightforward mesh extraction.
10
+ *
11
+ * Note: Meshes are often on child nodes (like "Body", "Axis") that don't
12
+ * have their own bsi::ifc::class. We associate these with the closest
13
+ * ancestor entity that has an expressId.
14
+ *
15
+ * Output geometry is converted to Y-up for the viewer.
16
+ */
17
+ export function extractGeometry(composed, pathToId) {
18
+ const meshes = [];
19
+ for (const node of composed.values()) {
20
+ const mesh = node.attributes.get(ATTR.MESH);
21
+ if (!mesh)
22
+ continue;
23
+ // Try to get expressId from this node, or walk up to parent entity
24
+ const expressId = getExpressIdFromHierarchy(node, pathToId);
25
+ if (expressId === undefined)
26
+ continue;
27
+ // Get IFC type from parent (mesh nodes are usually children of element nodes)
28
+ const ifcType = getIfcTypeFromHierarchy(node);
29
+ // Get accumulated transform from hierarchy
30
+ const transform = getAccumulatedTransform(node);
31
+ // Convert USD mesh to MeshData
32
+ const meshData = convertUsdMesh(mesh, expressId, ifcType, transform);
33
+ // Apply presentation attributes
34
+ applyPresentation(meshData, node);
35
+ meshes.push(meshData);
36
+ }
37
+ return meshes;
38
+ }
39
+ /**
40
+ * Get expressId by walking up the hierarchy to find an entity with an ID.
41
+ * This handles geometry on child nodes (like "Body") that don't have their own class.
42
+ */
43
+ function getExpressIdFromHierarchy(node, pathToId) {
44
+ let current = node;
45
+ while (current) {
46
+ const expressId = pathToId.get(current.path);
47
+ if (expressId !== undefined) {
48
+ return expressId;
49
+ }
50
+ current = current.parent;
51
+ }
52
+ return undefined;
53
+ }
54
+ /**
55
+ * Get IFC type by walking up the hierarchy to find a classified element.
56
+ */
57
+ function getIfcTypeFromHierarchy(node) {
58
+ let current = node;
59
+ while (current) {
60
+ const ifcClass = current.attributes.get(ATTR.CLASS);
61
+ if (ifcClass?.code) {
62
+ return ifcClass.code;
63
+ }
64
+ current = current.parent;
65
+ }
66
+ return undefined;
67
+ }
68
+ /**
69
+ * Convert USD mesh format to MeshData format.
70
+ * Applies transform in Z-up space, then converts to Y-up for the viewer.
71
+ */
72
+ function convertUsdMesh(usd, expressId, ifcType, transform) {
73
+ // Process points: apply transform in Z-up space, then convert to Y-up
74
+ const positions = new Float32Array(usd.points.length * 3);
75
+ for (let i = 0; i < usd.points.length; i++) {
76
+ const [x, y, z] = usd.points[i];
77
+ // World position in Z-up space
78
+ let wx, wy, wz;
79
+ if (transform) {
80
+ [wx, wy, wz] = applyTransform(x, y, z, transform);
81
+ }
82
+ else {
83
+ wx = x;
84
+ wy = y;
85
+ wz = z;
86
+ }
87
+ // Convert from Z-up to Y-up: swap Y and Z
88
+ // Z-up: X=right, Y=forward, Z=up
89
+ // Y-up: X=right, Y=up, Z=back (negated for right-hand rule)
90
+ positions[i * 3] = wx;
91
+ positions[i * 3 + 1] = wz; // Y-up = Z from Z-up
92
+ positions[i * 3 + 2] = -wy; // Z-back = -Y from Z-up
93
+ }
94
+ // Handle face vertex counts if present (for non-triangle faces)
95
+ let indices;
96
+ if (usd.faceVertexCounts && usd.faceVertexCounts.length > 0) {
97
+ indices = triangulatePolygons(usd.faceVertexIndices, usd.faceVertexCounts);
98
+ }
99
+ else {
100
+ // Already triangle indices
101
+ indices = new Uint32Array(usd.faceVertexIndices);
102
+ }
103
+ // Compute or use provided normals
104
+ const normals = usd.normals
105
+ ? flattenNormals(usd.normals, transform)
106
+ : computeNormals(positions, indices);
107
+ return {
108
+ expressId,
109
+ ifcType,
110
+ positions,
111
+ indices,
112
+ normals,
113
+ color: [0.8, 0.8, 0.8, 1.0], // Default gray, will be overridden by presentation
114
+ };
115
+ }
116
+ /**
117
+ * Triangulate polygon faces into triangles.
118
+ */
119
+ function triangulatePolygons(faceVertexIndices, faceVertexCounts) {
120
+ const triangles = [];
121
+ let indexOffset = 0;
122
+ for (const count of faceVertexCounts) {
123
+ // Fan triangulation
124
+ const v0 = faceVertexIndices[indexOffset];
125
+ for (let i = 1; i < count - 1; i++) {
126
+ triangles.push(v0);
127
+ triangles.push(faceVertexIndices[indexOffset + i]);
128
+ triangles.push(faceVertexIndices[indexOffset + i + 1]);
129
+ }
130
+ indexOffset += count;
131
+ }
132
+ return new Uint32Array(triangles);
133
+ }
134
+ /**
135
+ * Get accumulated transform from node to root (in Z-up space).
136
+ *
137
+ * For row-major matrices with right-multiply (point * matrix), transforms must
138
+ * be accumulated in child-to-parent order: child * parent * grandparent * root
139
+ */
140
+ function getAccumulatedTransform(node) {
141
+ const transforms = [];
142
+ // Walk from node (child) up to root (parent), collecting transforms
143
+ let current = node;
144
+ while (current) {
145
+ const xform = current.attributes.get(ATTR.TRANSFORM);
146
+ if (xform?.transform) {
147
+ // Flatten the matrix (no coordinate conversion needed - IFCX is Z-up)
148
+ const matrix = flattenMatrix(xform.transform);
149
+ // Push to end - builds array in child-to-parent order for row-major multiplication
150
+ transforms.push(matrix);
151
+ }
152
+ current = current.parent;
153
+ }
154
+ if (transforms.length === 0)
155
+ return null;
156
+ if (transforms.length === 1)
157
+ return transforms[0];
158
+ // Multiply transforms in child * parent * grandparent order (left to right)
159
+ // This is correct for row-major matrices where we do: point * accumulated_matrix
160
+ let result = transforms[0];
161
+ for (let i = 1; i < transforms.length; i++) {
162
+ result = multiplyMatrices(result, transforms[i]);
163
+ }
164
+ return result;
165
+ }
166
+ /**
167
+ * Flatten 2D matrix array to 1D Float32Array.
168
+ */
169
+ function flattenMatrix(m) {
170
+ // USD uses row-major 4x4 matrices
171
+ const result = new Float32Array(16);
172
+ for (let row = 0; row < 4; row++) {
173
+ for (let col = 0; col < 4; col++) {
174
+ result[row * 4 + col] = m[row]?.[col] ?? (row === col ? 1 : 0);
175
+ }
176
+ }
177
+ return result;
178
+ }
179
+ /**
180
+ * Apply 4x4 transform matrix to a point.
181
+ */
182
+ function applyTransform(x, y, z, m) {
183
+ // Row-major matrix multiplication with perspective divide
184
+ const w = m[3] * x + m[7] * y + m[11] * z + m[15];
185
+ return [
186
+ (m[0] * x + m[4] * y + m[8] * z + m[12]) / w,
187
+ (m[1] * x + m[5] * y + m[9] * z + m[13]) / w,
188
+ (m[2] * x + m[6] * y + m[10] * z + m[14]) / w,
189
+ ];
190
+ }
191
+ /**
192
+ * Apply presentation attributes (color, opacity) to mesh.
193
+ */
194
+ function applyPresentation(mesh, node) {
195
+ // Check this node and its ancestors for presentation attributes
196
+ let current = node;
197
+ while (current) {
198
+ const diffuse = current.attributes.get(ATTR.DIFFUSE_COLOR);
199
+ const opacity = current.attributes.get(ATTR.OPACITY);
200
+ if (diffuse) {
201
+ const [r, g, b] = diffuse;
202
+ const a = opacity ?? 1.0;
203
+ mesh.color = [r, g, b, a];
204
+ return;
205
+ }
206
+ current = current.parent;
207
+ }
208
+ }
209
+ /**
210
+ * Compute normals from triangle mesh.
211
+ */
212
+ function computeNormals(positions, indices) {
213
+ const normals = new Float32Array(positions.length);
214
+ for (let i = 0; i < indices.length; i += 3) {
215
+ const i0 = indices[i] * 3;
216
+ const i1 = indices[i + 1] * 3;
217
+ const i2 = indices[i + 2] * 3;
218
+ // Triangle vertices
219
+ const ax = positions[i0], ay = positions[i0 + 1], az = positions[i0 + 2];
220
+ const bx = positions[i1], by = positions[i1 + 1], bz = positions[i1 + 2];
221
+ const cx = positions[i2], cy = positions[i2 + 1], cz = positions[i2 + 2];
222
+ // Edge vectors
223
+ const e1x = bx - ax, e1y = by - ay, e1z = bz - az;
224
+ const e2x = cx - ax, e2y = cy - ay, e2z = cz - az;
225
+ // Cross product
226
+ const nx = e1y * e2z - e1z * e2y;
227
+ const ny = e1z * e2x - e1x * e2z;
228
+ const nz = e1x * e2y - e1y * e2x;
229
+ // Accumulate (will normalize later)
230
+ normals[i0] += nx;
231
+ normals[i0 + 1] += ny;
232
+ normals[i0 + 2] += nz;
233
+ normals[i1] += nx;
234
+ normals[i1 + 1] += ny;
235
+ normals[i1 + 2] += nz;
236
+ normals[i2] += nx;
237
+ normals[i2 + 1] += ny;
238
+ normals[i2 + 2] += nz;
239
+ }
240
+ // Normalize
241
+ for (let i = 0; i < normals.length; i += 3) {
242
+ const len = Math.sqrt(normals[i] ** 2 + normals[i + 1] ** 2 + normals[i + 2] ** 2);
243
+ if (len > 0) {
244
+ normals[i] /= len;
245
+ normals[i + 1] /= len;
246
+ normals[i + 2] /= len;
247
+ }
248
+ }
249
+ return normals;
250
+ }
251
+ /**
252
+ * Flatten 2D normals array to 1D, transform, and convert to Y-up.
253
+ */
254
+ function flattenNormals(normals, transform) {
255
+ const result = new Float32Array(normals.length * 3);
256
+ const hasTransform = transform !== null;
257
+ for (let i = 0; i < normals.length; i++) {
258
+ // Normal in Z-up space
259
+ let [nx, ny, nz] = normals[i];
260
+ if (hasTransform && transform) {
261
+ // Transform normal by upper 3x3 of matrix (rotation only)
262
+ const tnx = transform[0] * nx + transform[4] * ny + transform[8] * nz;
263
+ const tny = transform[1] * nx + transform[5] * ny + transform[9] * nz;
264
+ const tnz = transform[2] * nx + transform[6] * ny + transform[10] * nz;
265
+ // Renormalize
266
+ const len = Math.sqrt(tnx ** 2 + tny ** 2 + tnz ** 2);
267
+ if (len > 0) {
268
+ nx = tnx / len;
269
+ ny = tny / len;
270
+ nz = tnz / len;
271
+ }
272
+ else {
273
+ nx = tnx;
274
+ ny = tny;
275
+ nz = tnz;
276
+ }
277
+ }
278
+ // Convert from Z-up to Y-up (same as positions)
279
+ result[i * 3] = nx;
280
+ result[i * 3 + 1] = nz; // Y = Z
281
+ result[i * 3 + 2] = -ny; // Z = -Y
282
+ }
283
+ return result;
284
+ }
285
+ /**
286
+ * Multiply two 4x4 matrices (row-major).
287
+ */
288
+ function multiplyMatrices(a, b) {
289
+ const result = new Float32Array(16);
290
+ for (let row = 0; row < 4; row++) {
291
+ for (let col = 0; col < 4; col++) {
292
+ let sum = 0;
293
+ for (let k = 0; k < 4; k++) {
294
+ sum += a[row * 4 + k] * b[k * 4 + col];
295
+ }
296
+ result[row * 4 + col] = sum;
297
+ }
298
+ }
299
+ return result;
300
+ }
301
+ //# sourceMappingURL=geometry-extractor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry-extractor.js","sourceRoot":"","sources":["../src/geometry-extractor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Hierarchy Builder for IFCX
3
+ * Builds spatial hierarchy from composed nodes
4
+ */
5
+ import type { ComposedNode } from './types.js';
6
+ import type { SpatialHierarchy } from '@ifc-lite/data';
7
+ /**
8
+ * Build spatial hierarchy from composed IFCX nodes.
9
+ *
10
+ * IFCX hierarchy comes from children relationships:
11
+ * - Project -> Site -> Building -> Storey -> Elements
12
+ *
13
+ * We identify spatial structure elements by their bsi::ifc::class codes.
14
+ */
15
+ export declare function buildHierarchy(composed: Map<string, ComposedNode>, pathToId: Map<string, number>): SpatialHierarchy;
16
+ //# sourceMappingURL=hierarchy-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hierarchy-builder.d.ts","sourceRoot":"","sources":["../src/hierarchy-builder.ts"],"names":[],"mappings":"AAIA;;;GAGG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAY,MAAM,YAAY,CAAC;AAGzD,OAAO,KAAK,EAAE,gBAAgB,EAAe,MAAM,gBAAgB,CAAC;AAEpE;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAC5B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EACnC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,gBAAgB,CAoGlB"}