@ifc-lite/pointcloud 0.2.0 → 0.3.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/dist/formats/ascii-points.d.ts +61 -0
- package/dist/formats/ascii-points.d.ts.map +1 -0
- package/dist/formats/ascii-points.js +243 -0
- package/dist/formats/ascii-points.js.map +1 -0
- package/dist/formats/e57-decode.d.ts +28 -0
- package/dist/formats/e57-decode.d.ts.map +1 -0
- package/dist/formats/e57-decode.js +425 -0
- package/dist/formats/e57-decode.js.map +1 -0
- package/dist/formats/e57-page.d.ts +42 -0
- package/dist/formats/e57-page.d.ts.map +1 -0
- package/dist/formats/e57-page.js +107 -0
- package/dist/formats/e57-page.js.map +1 -0
- package/dist/formats/e57-xml.d.ts +55 -0
- package/dist/formats/e57-xml.d.ts.map +1 -0
- package/dist/formats/e57-xml.js +127 -0
- package/dist/formats/e57-xml.js.map +1 -0
- package/dist/formats/e57.d.ts +29 -117
- package/dist/formats/e57.d.ts.map +1 -1
- package/dist/formats/e57.js +51 -444
- package/dist/formats/e57.js.map +1 -1
- package/dist/formats/ifcx-points.js +13 -1
- package/dist/formats/ifcx-points.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/index.js.map +1 -1
- package/dist/streaming/ascii-points-source.d.ts +31 -0
- package/dist/streaming/ascii-points-source.d.ts.map +1 -0
- package/dist/streaming/ascii-points-source.js +83 -0
- package/dist/streaming/ascii-points-source.js.map +1 -0
- package/dist/streaming/decode-worker.js +5 -0
- package/dist/streaming/decode-worker.js.map +1 -1
- package/dist/streaming/e57-source.js +6 -1
- package/dist/streaming/e57-source.js.map +1 -1
- package/dist/streaming/laz-source.d.ts.map +1 -1
- package/dist/streaming/laz-source.js +33 -1
- package/dist/streaming/laz-source.js.map +1 -1
- package/dist/streaming/protocol.d.ts +1 -1
- package/dist/streaming/protocol.d.ts.map +1 -1
- package/dist/streaming/worker-client.d.ts +1 -1
- package/dist/streaming/worker-client.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
export interface PrototypeField {
|
|
2
|
+
name: string;
|
|
3
|
+
kind: 'Float' | 'ScaledInteger' | 'Integer';
|
|
4
|
+
precision?: 'single' | 'double';
|
|
5
|
+
scale?: number;
|
|
6
|
+
offset?: number;
|
|
7
|
+
minimum?: number;
|
|
8
|
+
maximum?: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Per-scan pose: rotation (unit quaternion w + xi + yj + zk) +
|
|
12
|
+
* translation (in source-frame metres). Optional because most
|
|
13
|
+
* single-scan exports don't need one — when absent we treat the
|
|
14
|
+
* scan as already in the file's global frame (identity pose).
|
|
15
|
+
*/
|
|
16
|
+
export interface E57Pose {
|
|
17
|
+
rotation: {
|
|
18
|
+
w: number;
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
z: number;
|
|
22
|
+
};
|
|
23
|
+
translation: {
|
|
24
|
+
x: number;
|
|
25
|
+
y: number;
|
|
26
|
+
z: number;
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
export interface Data3DEntry {
|
|
30
|
+
guid: string;
|
|
31
|
+
name?: string;
|
|
32
|
+
recordCount: number;
|
|
33
|
+
/** Logical offset into the file where the binary section begins. */
|
|
34
|
+
binaryFileOffset: number;
|
|
35
|
+
/** Field declarations in record order. */
|
|
36
|
+
prototype: PrototypeField[];
|
|
37
|
+
/**
|
|
38
|
+
* Per-Data3D pose that places the scan into the file's global
|
|
39
|
+
* frame. Applied by `decodeE57` before merging multi-scan files;
|
|
40
|
+
* single-scan files where the pose is identity / absent are no-ops.
|
|
41
|
+
*/
|
|
42
|
+
pose?: E57Pose;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Parse the E57 XML section.
|
|
46
|
+
*
|
|
47
|
+
* Uses our own minimal SAX-style parser (`xml-mini.ts`) instead of
|
|
48
|
+
* `DOMParser` because dedicated Web Workers — where the decode runs —
|
|
49
|
+
* don't expose DOMParser. The shape we need (e57Root → data3D →
|
|
50
|
+
* vectorChild → prototype) is shallow and attribute-heavy, well within
|
|
51
|
+
* the mini parser's scope.
|
|
52
|
+
*/
|
|
53
|
+
export declare function parseE57Xml(xmlText: string): Data3DEntry[];
|
|
54
|
+
export declare function findField(proto: PrototypeField[], name: string): PrototypeField | undefined;
|
|
55
|
+
//# sourceMappingURL=e57-xml.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e57-xml.d.ts","sourceRoot":"","sources":["../../src/formats/e57-xml.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,OAAO,GAAG,eAAe,GAAG,SAAS,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,GAAG,QAAQ,CAAC;IAChC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;GAKG;AACH,MAAM,WAAW,OAAO;IACtB,QAAQ,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACzD,WAAW,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAClD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC;IACzB,0CAA0C;IAC1C,SAAS,EAAE,cAAc,EAAE,CAAC;IAC5B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,WAAW,EAAE,CAmE1D;AA0BD,wBAAgB,SAAS,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,IAAI,EAAE,MAAM,GAAG,cAAc,GAAG,SAAS,CAE3F"}
|
|
@@ -0,0 +1,127 @@
|
|
|
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
|
+
* E57 XML model + parser.
|
|
6
|
+
*
|
|
7
|
+
* The XML carries the `data3D` structure: per-scan record counts, the
|
|
8
|
+
* binary CompressedVector fileOffset, and the prototype field
|
|
9
|
+
* declarations (`Float`, `Integer`, `ScaledInteger`) that describe the
|
|
10
|
+
* binary record layout.
|
|
11
|
+
*/
|
|
12
|
+
import { childByName, childrenByName, parseXml, textChild, } from '../xml-mini.js';
|
|
13
|
+
/**
|
|
14
|
+
* Parse the E57 XML section.
|
|
15
|
+
*
|
|
16
|
+
* Uses our own minimal SAX-style parser (`xml-mini.ts`) instead of
|
|
17
|
+
* `DOMParser` because dedicated Web Workers — where the decode runs —
|
|
18
|
+
* don't expose DOMParser. The shape we need (e57Root → data3D →
|
|
19
|
+
* vectorChild → prototype) is shallow and attribute-heavy, well within
|
|
20
|
+
* the mini parser's scope.
|
|
21
|
+
*/
|
|
22
|
+
export function parseE57Xml(xmlText) {
|
|
23
|
+
const root = parseXml(xmlText);
|
|
24
|
+
if (root.name !== 'e57Root') {
|
|
25
|
+
throw new Error(`E57: XML root is not <e57Root> (saw <${root.name || '?'}>)`);
|
|
26
|
+
}
|
|
27
|
+
const data3D = childByName(root, 'data3D');
|
|
28
|
+
if (!data3D)
|
|
29
|
+
return [];
|
|
30
|
+
const entries = [];
|
|
31
|
+
for (const scan of childrenByName(data3D, 'vectorChild')) {
|
|
32
|
+
const points = childByName(scan, 'points');
|
|
33
|
+
if (!points)
|
|
34
|
+
continue;
|
|
35
|
+
if (points.attrs.get('type') !== 'CompressedVector') {
|
|
36
|
+
// Skip non-compressed-vector points (rare).
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
const fileOffsetAttr = points.attrs.get('fileOffset');
|
|
40
|
+
const recordCountAttr = points.attrs.get('recordCount');
|
|
41
|
+
if (!fileOffsetAttr || !recordCountAttr)
|
|
42
|
+
continue;
|
|
43
|
+
// Reject NaN / negative parses up front. Without this guard a
|
|
44
|
+
// malformed XML attribute (e.g. fileOffset="-1" or
|
|
45
|
+
// recordCount="bogus") would flow into decodeE57Scan and either
|
|
46
|
+
// overrun the bytestream walk or allocate a zero-byte position
|
|
47
|
+
// buffer — neither produces a useful diagnostic.
|
|
48
|
+
const binaryFileOffset = Number(fileOffsetAttr);
|
|
49
|
+
const recordCount = Number(recordCountAttr);
|
|
50
|
+
if (!Number.isFinite(binaryFileOffset) || binaryFileOffset < 0)
|
|
51
|
+
continue;
|
|
52
|
+
if (!Number.isFinite(recordCount) || recordCount < 0)
|
|
53
|
+
continue;
|
|
54
|
+
const proto = childByName(points, 'prototype');
|
|
55
|
+
if (!proto)
|
|
56
|
+
continue;
|
|
57
|
+
const fields = [];
|
|
58
|
+
for (const f of proto.children) {
|
|
59
|
+
const type = f.attrs.get('type') ?? '';
|
|
60
|
+
if (type === 'Float') {
|
|
61
|
+
fields.push({
|
|
62
|
+
name: f.name,
|
|
63
|
+
kind: 'Float',
|
|
64
|
+
precision: f.attrs.get('precision') === 'single' ? 'single' : 'double',
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
else if (type === 'ScaledInteger') {
|
|
68
|
+
fields.push({
|
|
69
|
+
name: f.name,
|
|
70
|
+
kind: 'ScaledInteger',
|
|
71
|
+
scale: Number(f.attrs.get('scale') ?? '1'),
|
|
72
|
+
offset: Number(f.attrs.get('offset') ?? '0'),
|
|
73
|
+
minimum: Number(f.attrs.get('minimum') ?? '0'),
|
|
74
|
+
maximum: Number(f.attrs.get('maximum') ?? '0'),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
else if (type === 'Integer') {
|
|
78
|
+
fields.push({
|
|
79
|
+
name: f.name,
|
|
80
|
+
kind: 'Integer',
|
|
81
|
+
minimum: Number(f.attrs.get('minimum') ?? '0'),
|
|
82
|
+
maximum: Number(f.attrs.get('maximum') ?? '0'),
|
|
83
|
+
});
|
|
84
|
+
}
|
|
85
|
+
// Other types (e.g. String) ignored — never carry point data.
|
|
86
|
+
}
|
|
87
|
+
entries.push({
|
|
88
|
+
guid: textChild(scan, 'guid') ?? '',
|
|
89
|
+
name: textChild(scan, 'name') ?? undefined,
|
|
90
|
+
recordCount,
|
|
91
|
+
binaryFileOffset,
|
|
92
|
+
prototype: fields,
|
|
93
|
+
pose: parsePoseElement(childByName(scan, 'pose')) ?? undefined,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return entries;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Parse a `<pose>` element to a quaternion + translation pair.
|
|
100
|
+
* Returns null when the element is missing or malformed (any field
|
|
101
|
+
* unparseable → fall back to identity rather than reject the file).
|
|
102
|
+
*/
|
|
103
|
+
function parsePoseElement(poseEl) {
|
|
104
|
+
if (!poseEl)
|
|
105
|
+
return null;
|
|
106
|
+
const rotation = childByName(poseEl, 'rotation');
|
|
107
|
+
const translation = childByName(poseEl, 'translation');
|
|
108
|
+
if (!rotation || !translation)
|
|
109
|
+
return null;
|
|
110
|
+
const qw = Number(textChild(rotation, 'w') ?? '1');
|
|
111
|
+
const qx = Number(textChild(rotation, 'x') ?? '0');
|
|
112
|
+
const qy = Number(textChild(rotation, 'y') ?? '0');
|
|
113
|
+
const qz = Number(textChild(rotation, 'z') ?? '0');
|
|
114
|
+
const tx = Number(textChild(translation, 'x') ?? '0');
|
|
115
|
+
const ty = Number(textChild(translation, 'y') ?? '0');
|
|
116
|
+
const tz = Number(textChild(translation, 'z') ?? '0');
|
|
117
|
+
if (![qw, qx, qy, qz, tx, ty, tz].every(Number.isFinite))
|
|
118
|
+
return null;
|
|
119
|
+
return {
|
|
120
|
+
rotation: { w: qw, x: qx, y: qy, z: qz },
|
|
121
|
+
translation: { x: tx, y: ty, z: tz },
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
export function findField(proto, name) {
|
|
125
|
+
return proto.find((p) => p.name === name);
|
|
126
|
+
}
|
|
127
|
+
//# sourceMappingURL=e57-xml.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"e57-xml.js","sourceRoot":"","sources":["../../src/formats/e57-xml.ts"],"names":[],"mappings":"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"}
|
package/dist/formats/e57.d.ts
CHANGED
|
@@ -1,129 +1,41 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* E57 (ASTM E2807-11) reader —
|
|
2
|
+
* E57 (ASTM E2807-11) reader — top-level orchestrator.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* correct for well-formed files).
|
|
10
|
-
* - XML parsed with DOMParser to find Data3D entries with FloatNodes
|
|
11
|
-
* for cartesianX / cartesianY / cartesianZ and optional colorRed /
|
|
12
|
-
* colorGreen / colorBlue / intensity.
|
|
13
|
-
* - Binary section: walk DataPackets at the prototype's CompressedVector
|
|
14
|
-
* fileOffset, decode bytestreams as raw Float32 / Float64 columns.
|
|
15
|
-
*
|
|
16
|
-
* What we don't yet support:
|
|
17
|
-
* - ScaledIntegerNode encoding (bit-packed integers with scale/offset)
|
|
18
|
-
* — this is the more compact format; we throw a clear error so the
|
|
19
|
-
* caller can guide the user to a Float-encoded export.
|
|
20
|
-
* - Spherical coordinates (most files use cartesian).
|
|
21
|
-
* - Per-scan pose transforms — points come back in scan-local space.
|
|
4
|
+
* Pulls the file-header / page-CRC handling from `e57-page.ts`, the
|
|
5
|
+
* XML model from `e57-xml.ts`, and the per-scan binary decoder from
|
|
6
|
+
* `e57-decode.ts`. Re-exports the public surface so existing callers
|
|
7
|
+
* (`@ifc-lite/pointcloud` index, the streaming source, tests) keep
|
|
8
|
+
* working.
|
|
22
9
|
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
10
|
+
* Scope:
|
|
11
|
+
* - Single-scan + multi-scan files. Per-Data3D pose (quaternion +
|
|
12
|
+
* translation) is applied before merging so registered scans
|
|
13
|
+
* line up in the file's global frame.
|
|
14
|
+
* - Float (single/double) AND ScaledInteger (bit-packed integer
|
|
15
|
+
* with scale/offset per E57 §6.3.4) for cartesian fields.
|
|
16
|
+
* - Integer / Float / ScaledInteger colour + intensity channels.
|
|
17
|
+
*
|
|
18
|
+
* Out of scope (deferred — see issue #611):
|
|
19
|
+
* - Spherical coordinate prototypes.
|
|
26
20
|
*/
|
|
27
21
|
import type { DecodedPointChunk } from '../types.js';
|
|
28
|
-
|
|
29
|
-
majorVersion: number;
|
|
30
|
-
minorVersion: number;
|
|
31
|
-
fileLogicalSize: number;
|
|
32
|
-
xmlLogicalOffset: number;
|
|
33
|
-
xmlLogicalLength: number;
|
|
34
|
-
pageSize: number;
|
|
35
|
-
}
|
|
36
|
-
/** Read the 48-byte FileHeader. Throws on bad magic. */
|
|
37
|
-
export declare function parseE57FileHeader(bytes: Uint8Array): E57FileHeader;
|
|
38
|
-
/**
|
|
39
|
-
* Strip the 4-byte CRC tail from each `pageSize`-byte physical page.
|
|
40
|
-
*
|
|
41
|
-
* Returns a freshly-allocated buffer of "logical" bytes — the form that
|
|
42
|
-
* XML offsets and CompressedVector data offsets reference.
|
|
43
|
-
*
|
|
44
|
-
* `pageSize` is read from the header and is conventionally 1024.
|
|
45
|
-
*/
|
|
46
|
-
export declare function stripPageCrc(bytes: Uint8Array, pageSize: number): Uint8Array;
|
|
47
|
-
/**
|
|
48
|
-
* Read a CompressedVector binary-section header (E57 spec §6.4.2) and
|
|
49
|
-
* return the LOGICAL byte offset where its DataPackets actually start.
|
|
50
|
-
*
|
|
51
|
-
* Layout (32 bytes):
|
|
52
|
-
* [ 0] u8 sectionId (must == 1 for CompressedVector)
|
|
53
|
-
* [ 1] u8[7] reserved
|
|
54
|
-
* [ 8] u64 LE sectionLogicalLength
|
|
55
|
-
* [16] u64 LE dataPhysicalOffset
|
|
56
|
-
* [24] u64 LE indexPhysicalOffset
|
|
57
|
-
*
|
|
58
|
-
* The XML's `points@fileOffset` points at this section header — NOT at
|
|
59
|
-
* the first DataPacket. Reading packets straight at `fileOffset` puts
|
|
60
|
-
* the parser ~32 bytes off and the first u16 it reads is the low half
|
|
61
|
-
* of `sectionLogicalLength`, which usually decodes as a bytestreamCount
|
|
62
|
-
* of 0 (matched the user-reported `bytestreamCount (0) ≠ prototype
|
|
63
|
-
* length (7)` error exactly).
|
|
64
|
-
*/
|
|
65
|
-
export declare function resolveCompressedVectorDataOffset(logical: Uint8Array, physicalSectionOffset: number, pageSize: number): number;
|
|
66
|
-
interface PrototypeField {
|
|
67
|
-
name: string;
|
|
68
|
-
kind: 'Float' | 'ScaledInteger' | 'Integer';
|
|
69
|
-
precision?: 'single' | 'double';
|
|
70
|
-
scale?: number;
|
|
71
|
-
offset?: number;
|
|
72
|
-
minimum?: number;
|
|
73
|
-
maximum?: number;
|
|
74
|
-
}
|
|
75
|
-
export interface Data3DEntry {
|
|
76
|
-
guid: string;
|
|
77
|
-
name?: string;
|
|
78
|
-
recordCount: number;
|
|
79
|
-
/** Logical offset into the file where the binary section begins. */
|
|
80
|
-
binaryFileOffset: number;
|
|
81
|
-
/** Field declarations in record order. */
|
|
82
|
-
prototype: PrototypeField[];
|
|
83
|
-
/**
|
|
84
|
-
* Whether this Data3D defines a `pose` element (translation +
|
|
85
|
-
* rotation that places the scan in the file's global frame). We
|
|
86
|
-
* don't apply the transform yet — single-scan files don't need it,
|
|
87
|
-
* and multi-scan files with poses are rejected upfront so we never
|
|
88
|
-
* silently merge in scan-local space.
|
|
89
|
-
*/
|
|
90
|
-
hasPose?: boolean;
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Parse the E57 XML section.
|
|
94
|
-
*
|
|
95
|
-
* Uses our own minimal SAX-style parser (`xml-mini.ts`) instead of
|
|
96
|
-
* `DOMParser` because dedicated Web Workers — where the decode runs —
|
|
97
|
-
* don't expose DOMParser. The shape we need (e57Root → data3D →
|
|
98
|
-
* vectorChild → prototype) is shallow and attribute-heavy, well within
|
|
99
|
-
* the mini parser's scope.
|
|
100
|
-
*/
|
|
101
|
-
export declare function parseE57Xml(xmlText: string): Data3DEntry[];
|
|
102
|
-
/**
|
|
103
|
-
* Decode the binary section starting at `entry.binaryFileOffset` in the
|
|
104
|
-
* logical-bytes view. NOTE: `binaryFileOffset` here must already point
|
|
105
|
-
* at the first DataPacket (i.e. AFTER the 32-byte CompressedVector
|
|
106
|
-
* section header) — `decodeE57` does this conversion via
|
|
107
|
-
* `resolveCompressedVectorDataOffset`. Callers passing the raw XML
|
|
108
|
-
* offset directly will see a "bytestreamCount ≠ prototype length"
|
|
109
|
-
* mismatch.
|
|
110
|
-
*
|
|
111
|
-
* Returns one DecodedPointChunk per scan; caller can concatenate or
|
|
112
|
-
* emit them as separate streaming chunks.
|
|
113
|
-
*
|
|
114
|
-
* Limitations (Phase-1 E57):
|
|
115
|
-
* - Only Float (single/double) prototype fields are decoded. Files
|
|
116
|
-
* using ScaledInteger throw a clear error so the host can fall back
|
|
117
|
-
* gracefully.
|
|
118
|
-
* - Reads only cartesianX/Y/Z + colorRed/Green/Blue + intensity when
|
|
119
|
-
* present. Other fields are honoured for stride math but discarded.
|
|
120
|
-
*/
|
|
121
|
-
export declare function decodeE57Scan(logical: Uint8Array, entry: Data3DEntry): DecodedPointChunk;
|
|
22
|
+
import { type E57Pose } from './e57-xml.js';
|
|
122
23
|
/**
|
|
123
24
|
* Decode all Data3D scans in an E57 file. Combines them into a single
|
|
124
25
|
* DecodedPointChunk (positions concatenated). Returns null when the
|
|
125
26
|
* file has no scans.
|
|
126
27
|
*/
|
|
127
28
|
export declare function decodeE57(bytes: Uint8Array): DecodedPointChunk | null;
|
|
128
|
-
|
|
29
|
+
/**
|
|
30
|
+
* Apply a per-scan pose (rotation quaternion + translation) to a
|
|
31
|
+
* positions buffer in place: `out = R · in + T`.
|
|
32
|
+
*
|
|
33
|
+
* Quaternion is in Hamilton convention (w + xi + yj + zk); we derive
|
|
34
|
+
* the 3×3 rotation matrix once and reuse across every point in the
|
|
35
|
+
* chunk. Translation is added after rotation.
|
|
36
|
+
*/
|
|
37
|
+
export declare function applyPoseInPlace(positions: Float32Array, pointCount: number, pose: E57Pose): void;
|
|
38
|
+
export { parseE57FileHeader, stripPageCrc, resolveCompressedVectorDataOffset, type E57FileHeader, } from './e57-page.js';
|
|
39
|
+
export { parseE57Xml, type Data3DEntry, type E57Pose, } from './e57-xml.js';
|
|
40
|
+
export { decodeE57Scan } from './e57-decode.js';
|
|
129
41
|
//# sourceMappingURL=e57.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"e57.d.ts","sourceRoot":"","sources":["../../src/formats/e57.ts"],"names":[],"mappings":"AAIA
|
|
1
|
+
{"version":3,"file":"e57.d.ts","sourceRoot":"","sources":["../../src/formats/e57.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAMrD,OAAO,EAAe,KAAK,OAAO,EAAE,MAAM,cAAc,CAAC;AAKzD;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,iBAAiB,GAAG,IAAI,CAsDrE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,SAAS,EAAE,YAAY,EACvB,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,OAAO,GACZ,IAAI,CAsBN;AAGD,OAAO,EACL,kBAAkB,EAClB,YAAY,EACZ,iCAAiC,EACjC,KAAK,aAAa,GACnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,WAAW,EACX,KAAK,WAAW,EAChB,KAAK,OAAO,GACb,MAAM,cAAc,CAAC;AACtB,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
|