@ifc-lite/ifcx 4.3.0 → 4.5.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/README.md +12 -0
- package/dist/detect-format.d.ts +5 -0
- package/dist/detect-format.d.ts.map +1 -0
- package/dist/detect-format.js +33 -0
- package/dist/detect-format.js.map +1 -0
- package/dist/generated/imported-geometry-static.js +17116 -0
- package/dist/generated/imported-geometry.d.ts +2 -0
- package/dist/generated/imported-geometry.d.ts.map +1 -0
- package/dist/generated/imported-geometry.js +13 -0
- package/dist/generated/imported-geometry.js.map +1 -0
- package/dist/geometry-extractor.d.ts +2 -16
- package/dist/geometry-extractor.d.ts.map +1 -1
- package/dist/geometry-extractor.js +3 -299
- package/dist/geometry-extractor.js.map +1 -1
- package/dist/georeference.d.ts +17 -0
- package/dist/georeference.d.ts.map +1 -0
- package/dist/georeference.js +44 -0
- package/dist/georeference.js.map +1 -0
- package/dist/imported-graph-source.d.ts +13 -0
- package/dist/imported-graph-source.d.ts.map +1 -0
- package/dist/imported-graph-source.js +53 -0
- package/dist/imported-graph-source.js.map +1 -0
- package/dist/imported-graph.d.ts +13 -0
- package/dist/imported-graph.d.ts.map +1 -0
- package/dist/imported-graph.js +154 -0
- package/dist/imported-graph.js.map +1 -0
- package/dist/imported-kernel.d.ts +33 -0
- package/dist/imported-kernel.d.ts.map +1 -0
- package/dist/imported-kernel.js +172 -0
- package/dist/imported-kernel.js.map +1 -0
- package/dist/imported-scene.d.ts +7 -0
- package/dist/imported-scene.d.ts.map +1 -0
- package/dist/imported-scene.js +6 -0
- package/dist/imported-scene.js.map +1 -0
- package/dist/imported-snapshot.d.ts +3 -0
- package/dist/imported-snapshot.d.ts.map +1 -0
- package/dist/imported-snapshot.js +53 -0
- package/dist/imported-snapshot.js.map +1 -0
- package/dist/imported-source.d.ts +59 -0
- package/dist/imported-source.d.ts.map +1 -0
- package/dist/imported-source.js +96 -0
- package/dist/imported-source.js.map +1 -0
- package/dist/imported-wire.d.ts +35 -0
- package/dist/imported-wire.d.ts.map +1 -0
- package/dist/imported-wire.js +108 -0
- package/dist/imported-wire.js.map +1 -0
- package/dist/index.d.ts +3 -49
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +36 -51
- package/dist/index.js.map +1 -1
- package/dist/parse-result.d.ts +48 -0
- package/dist/parse-result.d.ts.map +1 -0
- package/dist/parse-result.js +5 -0
- package/dist/parse-result.js.map +1 -0
- package/dist/pointcloud-extractor.d.ts +14 -0
- package/dist/pointcloud-extractor.d.ts.map +1 -1
- package/dist/pointcloud-extractor.js +3 -176
- package/dist/pointcloud-extractor.js.map +1 -1
- package/package.json +6 -5
- package/dist/geometry-normals.d.ts +0 -29
- package/dist/geometry-normals.d.ts.map +0 -1
- package/dist/geometry-normals.js +0 -91
- package/dist/geometry-normals.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-result.d.ts","sourceRoot":"","sources":["../src/parse-result.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,gBAAgB,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAClI,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,mBAAmB,CAAC;AAE7D;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,4BAA4B;IAC5B,QAAQ,EAAE,WAAW,CAAC;IACtB,8BAA8B;IAC9B,UAAU,EAAE,aAAa,CAAC;IAC1B,8BAA8B;IAC9B,UAAU,EAAE,aAAa,CAAC;IAC1B,yBAAyB;IACzB,aAAa,EAAE,iBAAiB,CAAC;IACjC,wBAAwB;IACxB,gBAAgB,EAAE,gBAAgB,CAAC;IACnC,wCAAwC;IACxC,OAAO,EAAE,WAAW,CAAC;IACrB,sCAAsC;IACtC,MAAM,EAAE,QAAQ,EAAE,CAAC;IACnB,wEAAwE;IACxE,WAAW,EAAE,oBAAoB,EAAE,CAAC;IACpC,2CAA2C;IAC3C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,2CAA2C;IAC3C,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,qBAAqB;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,yBAAyB;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,WAAW,EAAE,MAAM,CAAC;IACpB,iCAAiC;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,mFAAmF;IACnF,cAAc,CAAC,EAAE,UAAU,CAAC,OAAO,mBAAmB,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,gBAAgB;IAC/B,wBAAwB;IACxB,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACrE"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-result.js","sourceRoot":"","sources":["../src/parse-result.ts"],"names":[],"mappings":"AAAA;;+DAE+D"}
|
|
@@ -1,3 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Point cloud extractor for IFCX.
|
|
3
|
+
*
|
|
4
|
+
* Reads the three buildingSMART point cloud schemas:
|
|
5
|
+
* - `pcd::base64` — full PCD file embedded as base64
|
|
6
|
+
* - `points::array` — inline JSON arrays of [x,y,z] (and optional rgb)
|
|
7
|
+
* - `points::base64` — base64-Float32 buffers
|
|
8
|
+
*
|
|
9
|
+
* Coordinates: positions are extracted in IFCx-native Z-up space, with any
|
|
10
|
+
* `usd::xformop` lineage transform applied. The extractor swaps Y/Z to
|
|
11
|
+
* match the viewer's Y-up convention — same convention as the mesh
|
|
12
|
+
* extractor (see geometry-extractor.ts).
|
|
13
|
+
*/
|
|
1
14
|
import type { ComposedNode } from './types.js';
|
|
2
15
|
export interface PointCloudExtraction {
|
|
3
16
|
expressId: number;
|
|
@@ -10,5 +23,6 @@ export interface PointCloudExtraction {
|
|
|
10
23
|
max: [number, number, number];
|
|
11
24
|
};
|
|
12
25
|
}
|
|
26
|
+
/** Synchronous no-setup adapter; point codecs retain their existing authority. */
|
|
13
27
|
export declare function extractPointClouds(composed: Map<string, ComposedNode>, pathToId: Map<string, number>): PointCloudExtraction[];
|
|
14
28
|
//# sourceMappingURL=pointcloud-extractor.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointcloud-extractor.d.ts","sourceRoot":"","sources":["../src/pointcloud-extractor.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"pointcloud-extractor.d.ts","sourceRoot":"","sources":["../src/pointcloud-extractor.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,MAAM,WAAW,oBAAoB;IACnC,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,YAAY,CAAC;IACxB,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE;QAAE,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;KAAE,CAAC;CACxE;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,EAAE,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,oBAAoB,EAAE,CAE7H"}
|
|
@@ -1,182 +1,9 @@
|
|
|
1
1
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
2
2
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
3
3
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
*
|
|
7
|
-
* Reads the three buildingSMART point cloud schemas:
|
|
8
|
-
* - `pcd::base64` — full PCD file embedded as base64
|
|
9
|
-
* - `points::array` — inline JSON arrays of [x,y,z] (and optional rgb)
|
|
10
|
-
* - `points::base64` — base64-Float32 buffers
|
|
11
|
-
*
|
|
12
|
-
* Coordinates: positions are extracted in IFCx-native Z-up space, with any
|
|
13
|
-
* `usd::xformop` lineage transform applied. The extractor swaps Y/Z to
|
|
14
|
-
* match the viewer's Y-up convention — same convention as the mesh
|
|
15
|
-
* extractor (see geometry-extractor.ts).
|
|
16
|
-
*/
|
|
17
|
-
import { decodeIfcxPointAttribute, POINTCLOUD_ATTR_KEYS } from '@ifc-lite/pointcloud';
|
|
18
|
-
import { ATTR } from './types.js';
|
|
19
|
-
import { getNodeLineage, walkComposedFrames } from './traversal.js';
|
|
4
|
+
import { executeImportedGraph } from './imported-graph.js';
|
|
5
|
+
/** Synchronous no-setup adapter; point codecs retain their existing authority. */
|
|
20
6
|
export function extractPointClouds(composed, pathToId) {
|
|
21
|
-
|
|
22
|
-
const contextByFrame = new WeakMap();
|
|
23
|
-
const transformByFrame = new WeakMap();
|
|
24
|
-
walkComposedFrames(composed, (frame) => {
|
|
25
|
-
const inheritedContext = frame.parent ? contextByFrame.get(frame.parent) ?? null : null;
|
|
26
|
-
const parentTransform = frame.parent ? transformByFrame.get(frame.parent) ?? null : null;
|
|
27
|
-
const context = resolveContext(frame.node, inheritedContext, pathToId);
|
|
28
|
-
const transform = combineTransforms(getNodeTransform(frame.node), parentTransform);
|
|
29
|
-
contextByFrame.set(frame, context);
|
|
30
|
-
transformByFrame.set(frame, transform);
|
|
31
|
-
if (!context || context.isTypeDefinition)
|
|
32
|
-
return;
|
|
33
|
-
if (!hasAnyPointAttr(frame.node.attributes))
|
|
34
|
-
return;
|
|
35
|
-
if (isInvisible(getNodeLineage(frame)))
|
|
36
|
-
return;
|
|
37
|
-
const chunk = decodeIfcxPointAttribute(frame.node.attributes);
|
|
38
|
-
if (!chunk)
|
|
39
|
-
return;
|
|
40
|
-
transformPositionsZUpToYUp(chunk.positions, transform);
|
|
41
|
-
out.push({
|
|
42
|
-
expressId: context.expressId,
|
|
43
|
-
ifcType: context.ifcType,
|
|
44
|
-
positions: chunk.positions,
|
|
45
|
-
colors: chunk.colors,
|
|
46
|
-
pointCount: chunk.pointCount,
|
|
47
|
-
bbox: recomputeBBox(chunk.positions),
|
|
48
|
-
});
|
|
49
|
-
});
|
|
50
|
-
return out;
|
|
51
|
-
}
|
|
52
|
-
function resolveContext(node, parent, pathToId) {
|
|
53
|
-
const ifcClass = node.attributes.get(ATTR.CLASS);
|
|
54
|
-
const expressId = pathToId.get(node.path);
|
|
55
|
-
if (expressId === undefined)
|
|
56
|
-
return parent;
|
|
57
|
-
return {
|
|
58
|
-
expressId,
|
|
59
|
-
ifcType: ifcClass?.code,
|
|
60
|
-
isTypeDefinition: (parent?.isTypeDefinition ?? false) || isIfcTypeDefinition(node),
|
|
61
|
-
};
|
|
62
|
-
}
|
|
63
|
-
function hasAnyPointAttr(attrs) {
|
|
64
|
-
for (const key of POINTCLOUD_ATTR_KEYS) {
|
|
65
|
-
if (attrs.has(key))
|
|
66
|
-
return true;
|
|
67
|
-
}
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
function getNodeTransform(node) {
|
|
71
|
-
const xform = node.attributes.get(ATTR.TRANSFORM);
|
|
72
|
-
return xform?.transform ? flattenMatrix(xform.transform) : null;
|
|
73
|
-
}
|
|
74
|
-
function combineTransforms(nodeTransform, parentTransform) {
|
|
75
|
-
if (!nodeTransform)
|
|
76
|
-
return parentTransform;
|
|
77
|
-
if (!parentTransform)
|
|
78
|
-
return nodeTransform;
|
|
79
|
-
return multiplyMatrices(nodeTransform, parentTransform);
|
|
80
|
-
}
|
|
81
|
-
function flattenMatrix(m) {
|
|
82
|
-
// USD `xformop` matrices use ROW-major layout with the convention
|
|
83
|
-
// `point' = point × M` — translation lives in row 3 (m[3][0..2]).
|
|
84
|
-
// Flattened as result[row*4+col], that puts tx/ty/tz at indices
|
|
85
|
-
// 12/13/14, which is exactly what transformPositionsZUpToYUp reads
|
|
86
|
-
// (`transform[12]` etc.). Don't transpose this — it would break the
|
|
87
|
-
// S1 buildingSMART sample which has its translation specifically in
|
|
88
|
-
// row 3.
|
|
89
|
-
const result = new Float32Array(16);
|
|
90
|
-
for (let row = 0; row < 4; row++) {
|
|
91
|
-
for (let col = 0; col < 4; col++) {
|
|
92
|
-
result[row * 4 + col] = m[row]?.[col] ?? (row === col ? 1 : 0);
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
return result;
|
|
96
|
-
}
|
|
97
|
-
function multiplyMatrices(a, b) {
|
|
98
|
-
const result = new Float32Array(16);
|
|
99
|
-
for (let row = 0; row < 4; row++) {
|
|
100
|
-
for (let col = 0; col < 4; col++) {
|
|
101
|
-
let sum = 0;
|
|
102
|
-
for (let k = 0; k < 4; k++) {
|
|
103
|
-
sum += a[row * 4 + k] * b[k * 4 + col];
|
|
104
|
-
}
|
|
105
|
-
result[row * 4 + col] = sum;
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
return result;
|
|
109
|
-
}
|
|
110
|
-
function isIfcTypeDefinition(node) {
|
|
111
|
-
const customData = node.attributes.get('customdata');
|
|
112
|
-
const originalStepInstance = customData?.originalStepInstance;
|
|
113
|
-
if (typeof originalStepInstance !== 'string')
|
|
114
|
-
return false;
|
|
115
|
-
return /=[A-Za-z0-9_]*Type\(/i.test(originalStepInstance);
|
|
116
|
-
}
|
|
117
|
-
function isInvisible(lineage) {
|
|
118
|
-
for (let i = lineage.length - 1; i >= 0; i--) {
|
|
119
|
-
const visibility = lineage[i].attributes.get(ATTR.VISIBILITY);
|
|
120
|
-
if (typeof visibility?.visibility === 'string') {
|
|
121
|
-
return visibility.visibility.toLowerCase() === 'invisible';
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
return false;
|
|
125
|
-
}
|
|
126
|
-
// ─── geometry math (z-up → y-up, in-place on the decoded positions) ─────────
|
|
127
|
-
function transformPositionsZUpToYUp(positions, transform) {
|
|
128
|
-
// Pre-validate the homogeneous denominator using a representative point
|
|
129
|
-
// (the first one). USD `xformop` matrices are typically affine — w is
|
|
130
|
-
// either 1 (identity-bottom-row) or a rigid-body homogeneous coord — so
|
|
131
|
-
// checking the first point is sufficient to catch a malformed file.
|
|
132
|
-
// Without the guard, a zero-w matrix produces ±Infinity / NaN
|
|
133
|
-
// coordinates and a poisoned bbox.
|
|
134
|
-
if (transform && positions.length >= 3) {
|
|
135
|
-
const x0 = positions[0], y0 = positions[1], z0 = positions[2];
|
|
136
|
-
const w = transform[3] * x0 + transform[7] * y0 + transform[11] * z0 + transform[15];
|
|
137
|
-
if (!Number.isFinite(w) || Math.abs(w) < 1e-12) {
|
|
138
|
-
throw new Error('IFCx pointcloud: usd::xformop produces non-finite homogeneous w; ' +
|
|
139
|
-
'matrix is malformed or singular');
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
for (let i = 0; i < positions.length; i += 3) {
|
|
143
|
-
const x = positions[i], y = positions[i + 1], z = positions[i + 2];
|
|
144
|
-
let wx, wy, wz;
|
|
145
|
-
if (transform) {
|
|
146
|
-
const w = transform[3] * x + transform[7] * y + transform[11] * z + transform[15];
|
|
147
|
-
const invW = 1 / w;
|
|
148
|
-
wx = (transform[0] * x + transform[4] * y + transform[8] * z + transform[12]) * invW;
|
|
149
|
-
wy = (transform[1] * x + transform[5] * y + transform[9] * z + transform[13]) * invW;
|
|
150
|
-
wz = (transform[2] * x + transform[6] * y + transform[10] * z + transform[14]) * invW;
|
|
151
|
-
}
|
|
152
|
-
else {
|
|
153
|
-
wx = x;
|
|
154
|
-
wy = y;
|
|
155
|
-
wz = z;
|
|
156
|
-
}
|
|
157
|
-
positions[i] = wx;
|
|
158
|
-
positions[i + 1] = wz; // Y-up = Z from Z-up
|
|
159
|
-
positions[i + 2] = -wy; // Z-back = -Y from Z-up
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
function recomputeBBox(positions) {
|
|
163
|
-
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
164
|
-
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
165
|
-
for (let i = 0; i < positions.length; i += 3) {
|
|
166
|
-
const x = positions[i], y = positions[i + 1], z = positions[i + 2];
|
|
167
|
-
if (x < minX)
|
|
168
|
-
minX = x;
|
|
169
|
-
if (x > maxX)
|
|
170
|
-
maxX = x;
|
|
171
|
-
if (y < minY)
|
|
172
|
-
minY = y;
|
|
173
|
-
if (y > maxY)
|
|
174
|
-
maxY = y;
|
|
175
|
-
if (z < minZ)
|
|
176
|
-
minZ = z;
|
|
177
|
-
if (z > maxZ)
|
|
178
|
-
maxZ = z;
|
|
179
|
-
}
|
|
180
|
-
return { min: [minX, minY, minZ], max: [maxX, maxY, maxZ] };
|
|
7
|
+
return executeImportedGraph(composed, pathToId, 2).pointClouds;
|
|
181
8
|
}
|
|
182
9
|
//# sourceMappingURL=pointcloud-extractor.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"pointcloud-extractor.js","sourceRoot":"","sources":["../src/pointcloud-extractor.ts"],"names":[],"mappings":"AAAA;;+DAE+D;
|
|
1
|
+
{"version":3,"file":"pointcloud-extractor.js","sourceRoot":"","sources":["../src/pointcloud-extractor.ts"],"names":[],"mappings":"AAAA;;+DAE+D;AAiB/D,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAW3D,kFAAkF;AAClF,MAAM,UAAU,kBAAkB,CAAC,QAAmC,EAAE,QAA6B;IACnG,OAAO,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;AACjE,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ifc-lite/ifcx",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.5.0",
|
|
4
4
|
"description": "IFC5 (IFCX) parser for IFC-Lite",
|
|
5
5
|
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
6
7
|
"main": "./dist/index.js",
|
|
7
8
|
"types": "./dist/index.d.ts",
|
|
8
9
|
"exports": {
|
|
@@ -14,9 +15,9 @@
|
|
|
14
15
|
},
|
|
15
16
|
"dependencies": {
|
|
16
17
|
"@noble/hashes": "^2.4.0",
|
|
17
|
-
"@ifc-lite/
|
|
18
|
-
"@ifc-lite/
|
|
19
|
-
"@ifc-lite/pointcloud": "^0.
|
|
18
|
+
"@ifc-lite/data": "^6.3.0",
|
|
19
|
+
"@ifc-lite/mutations": "^3.2.0",
|
|
20
|
+
"@ifc-lite/pointcloud": "^0.13.0"
|
|
20
21
|
},
|
|
21
22
|
"devDependencies": {
|
|
22
23
|
"tsx": "^4.23.15",
|
|
@@ -47,7 +48,7 @@
|
|
|
47
48
|
"README.md"
|
|
48
49
|
],
|
|
49
50
|
"scripts": {
|
|
50
|
-
"build": "pnpm exec tsc && node ./scripts/verify-dist-hello-wall.mjs",
|
|
51
|
+
"build": "node ../../scripts/build-imported-geometry.mjs --verify && pnpm exec tsc && node ../../scripts/build-imported-geometry.mjs --copy && node ./scripts/verify-dist-hello-wall.mjs",
|
|
51
52
|
"typecheck": "node ../../scripts/typecheck-tests.mjs",
|
|
52
53
|
"dev": "pnpm exec tsc --watch",
|
|
53
54
|
"test": "tsx --test src/*.test.ts"
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Compute the normal-transform matrix for a local-to-world affine
|
|
3
|
-
* transform: the inverse-transpose of its upper-left 3x3 linear part.
|
|
4
|
-
*
|
|
5
|
-
* Positions transform as `v' = v * M` (row vector, M row-major — see
|
|
6
|
-
* `applyTransform`/`combineTransforms` in geometry-extractor.ts). Under
|
|
7
|
-
* that convention, a vector `e` tangent to the surface (an edge)
|
|
8
|
-
* transforms as `e' = e * M`, and the transformed normal `n'` must satisfy
|
|
9
|
-
* `n' . e' = 0` whenever `n . e = 0`. Substituting shows
|
|
10
|
-
* `n' = n * inverse(M)^T`, which reduces to `n' = n * M` only when M is
|
|
11
|
-
* orthogonal (M^-1 = M^T) — true for pure rotation, false under
|
|
12
|
-
* non-uniform scale or shear (a real `usd::xformop` shape: see
|
|
13
|
-
* `tests/models/ifc5/Tunnel_Excavation_07_Invert.ifcx`).
|
|
14
|
-
*
|
|
15
|
-
* `inverse(M)^T` equals `cofactor(M) / det(M)` (the adjugate is
|
|
16
|
-
* `cofactor(M)^T`, so its transpose is `cofactor(M)` again), so this
|
|
17
|
-
* returns the cofactor matrix scaled by `1/det`, flattened row-major.
|
|
18
|
-
* Returns null for a singular or non-finite linear part (degenerate
|
|
19
|
-
* transform; callers fall back to the untransformed normal).
|
|
20
|
-
*/
|
|
21
|
-
export declare function computeNormalMatrix(m: Float32Array): Float32Array | null;
|
|
22
|
-
/**
|
|
23
|
-
* Compute per-vertex normals from a triangle mesh by accumulating each
|
|
24
|
-
* triangle's face normal (cross product of its edges) at its three
|
|
25
|
-
* vertices, then normalizing. Used when a `usd::usdgeom::mesh` node omits
|
|
26
|
-
* explicit `normals`.
|
|
27
|
-
*/
|
|
28
|
-
export declare function computeNormals(positions: Float32Array, indices: Uint32Array): Float32Array;
|
|
29
|
-
//# sourceMappingURL=geometry-normals.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"geometry-normals.d.ts","sourceRoot":"","sources":["../src/geometry-normals.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,mBAAmB,CAAC,CAAC,EAAE,YAAY,GAAG,YAAY,GAAG,IAAI,CAwBxE;AAED;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,GAAG,YAAY,CAuC1F"}
|
package/dist/geometry-normals.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
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
|
-
/**
|
|
5
|
-
* Compute the normal-transform matrix for a local-to-world affine
|
|
6
|
-
* transform: the inverse-transpose of its upper-left 3x3 linear part.
|
|
7
|
-
*
|
|
8
|
-
* Positions transform as `v' = v * M` (row vector, M row-major — see
|
|
9
|
-
* `applyTransform`/`combineTransforms` in geometry-extractor.ts). Under
|
|
10
|
-
* that convention, a vector `e` tangent to the surface (an edge)
|
|
11
|
-
* transforms as `e' = e * M`, and the transformed normal `n'` must satisfy
|
|
12
|
-
* `n' . e' = 0` whenever `n . e = 0`. Substituting shows
|
|
13
|
-
* `n' = n * inverse(M)^T`, which reduces to `n' = n * M` only when M is
|
|
14
|
-
* orthogonal (M^-1 = M^T) — true for pure rotation, false under
|
|
15
|
-
* non-uniform scale or shear (a real `usd::xformop` shape: see
|
|
16
|
-
* `tests/models/ifc5/Tunnel_Excavation_07_Invert.ifcx`).
|
|
17
|
-
*
|
|
18
|
-
* `inverse(M)^T` equals `cofactor(M) / det(M)` (the adjugate is
|
|
19
|
-
* `cofactor(M)^T`, so its transpose is `cofactor(M)` again), so this
|
|
20
|
-
* returns the cofactor matrix scaled by `1/det`, flattened row-major.
|
|
21
|
-
* Returns null for a singular or non-finite linear part (degenerate
|
|
22
|
-
* transform; callers fall back to the untransformed normal).
|
|
23
|
-
*/
|
|
24
|
-
export function computeNormalMatrix(m) {
|
|
25
|
-
const a00 = m[0], a01 = m[1], a02 = m[2];
|
|
26
|
-
const a10 = m[4], a11 = m[5], a12 = m[6];
|
|
27
|
-
const a20 = m[8], a21 = m[9], a22 = m[10];
|
|
28
|
-
const det = a00 * (a11 * a22 - a12 * a21) -
|
|
29
|
-
a01 * (a10 * a22 - a12 * a20) +
|
|
30
|
-
a02 * (a10 * a21 - a11 * a20);
|
|
31
|
-
if (!Number.isFinite(det) || Math.abs(det) < 1e-12)
|
|
32
|
-
return null;
|
|
33
|
-
const invDet = 1 / det;
|
|
34
|
-
const result = new Float32Array(9);
|
|
35
|
-
result[0] = (a11 * a22 - a12 * a21) * invDet;
|
|
36
|
-
result[1] = -(a10 * a22 - a12 * a20) * invDet;
|
|
37
|
-
result[2] = (a10 * a21 - a11 * a20) * invDet;
|
|
38
|
-
result[3] = -(a01 * a22 - a02 * a21) * invDet;
|
|
39
|
-
result[4] = (a00 * a22 - a02 * a20) * invDet;
|
|
40
|
-
result[5] = -(a00 * a21 - a01 * a20) * invDet;
|
|
41
|
-
result[6] = (a01 * a12 - a02 * a11) * invDet;
|
|
42
|
-
result[7] = -(a00 * a12 - a02 * a10) * invDet;
|
|
43
|
-
result[8] = (a00 * a11 - a01 * a10) * invDet;
|
|
44
|
-
return result;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Compute per-vertex normals from a triangle mesh by accumulating each
|
|
48
|
-
* triangle's face normal (cross product of its edges) at its three
|
|
49
|
-
* vertices, then normalizing. Used when a `usd::usdgeom::mesh` node omits
|
|
50
|
-
* explicit `normals`.
|
|
51
|
-
*/
|
|
52
|
-
export function computeNormals(positions, indices) {
|
|
53
|
-
const normals = new Float32Array(positions.length);
|
|
54
|
-
for (let i = 0; i < indices.length; i += 3) {
|
|
55
|
-
const i0 = indices[i] * 3;
|
|
56
|
-
const i1 = indices[i + 1] * 3;
|
|
57
|
-
const i2 = indices[i + 2] * 3;
|
|
58
|
-
// Triangle vertices
|
|
59
|
-
const ax = positions[i0], ay = positions[i0 + 1], az = positions[i0 + 2];
|
|
60
|
-
const bx = positions[i1], by = positions[i1 + 1], bz = positions[i1 + 2];
|
|
61
|
-
const cx = positions[i2], cy = positions[i2 + 1], cz = positions[i2 + 2];
|
|
62
|
-
// Edge vectors
|
|
63
|
-
const e1x = bx - ax, e1y = by - ay, e1z = bz - az;
|
|
64
|
-
const e2x = cx - ax, e2y = cy - ay, e2z = cz - az;
|
|
65
|
-
// Cross product
|
|
66
|
-
const nx = e1y * e2z - e1z * e2y;
|
|
67
|
-
const ny = e1z * e2x - e1x * e2z;
|
|
68
|
-
const nz = e1x * e2y - e1y * e2x;
|
|
69
|
-
// Accumulate (will normalize later)
|
|
70
|
-
normals[i0] += nx;
|
|
71
|
-
normals[i0 + 1] += ny;
|
|
72
|
-
normals[i0 + 2] += nz;
|
|
73
|
-
normals[i1] += nx;
|
|
74
|
-
normals[i1 + 1] += ny;
|
|
75
|
-
normals[i1 + 2] += nz;
|
|
76
|
-
normals[i2] += nx;
|
|
77
|
-
normals[i2 + 1] += ny;
|
|
78
|
-
normals[i2 + 2] += nz;
|
|
79
|
-
}
|
|
80
|
-
// Normalize
|
|
81
|
-
for (let i = 0; i < normals.length; i += 3) {
|
|
82
|
-
const len = Math.sqrt(normals[i] ** 2 + normals[i + 1] ** 2 + normals[i + 2] ** 2);
|
|
83
|
-
if (len > 0) {
|
|
84
|
-
normals[i] /= len;
|
|
85
|
-
normals[i + 1] /= len;
|
|
86
|
-
normals[i + 2] /= len;
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
return normals;
|
|
90
|
-
}
|
|
91
|
-
//# sourceMappingURL=geometry-normals.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"geometry-normals.js","sourceRoot":"","sources":["../src/geometry-normals.ts"],"names":[],"mappings":"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"}
|