@loaders.gl/tile-converter 5.0.0-alpha.10 → 5.0.0-alpha.12

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 (107) hide show
  1. package/README.md +211 -2
  2. package/bin/converter-v5.js +2 -0
  3. package/dist/converter.min.cjs +162 -163
  4. package/dist/i3s-server/bin/i3s-server.min.cjs +73 -73
  5. package/dist/index.cjs +1933 -2232
  6. package/dist/index.js +1925 -2235
  7. package/dist/v5/adapters.cjs +3186 -208
  8. package/dist/v5/adapters.d.ts +29 -2
  9. package/dist/v5/adapters.js +3202 -196
  10. package/dist/v5/archive-source.d.ts +36 -0
  11. package/dist/v5/browser-tileset-source.d.ts +55 -11
  12. package/dist/v5/browser.cjs +30 -0
  13. package/dist/v5/browser.d.ts +26 -2
  14. package/dist/v5/browser.js +45 -1
  15. package/dist/v5/conversion-api.d.ts +9 -0
  16. package/dist/v5/converter-cli.d.ts +1 -0
  17. package/dist/v5/converter-cli.js +1214 -0
  18. package/dist/v5/core.cjs +515 -50
  19. package/dist/v5/core.d.ts +2 -0
  20. package/dist/v5/core.js +515 -50
  21. package/dist/v5/i3s-mesh-conversion.d.ts +14 -4
  22. package/dist/v5/i3s-mesh-sink.d.ts +25 -0
  23. package/dist/v5/i3s-mesh-source-features.d.ts +13 -0
  24. package/dist/v5/i3s-mesh-source-material.d.ts +5 -0
  25. package/dist/v5/i3s-mesh-source.d.ts +30 -0
  26. package/dist/v5/i3s-selection-source.d.ts +70 -0
  27. package/dist/v5/index.cjs +20 -0
  28. package/dist/v5/index.d.ts +18 -2
  29. package/dist/v5/index.js +31 -1
  30. package/dist/v5/mesh-conversion.d.ts +29 -2
  31. package/dist/v5/mesh-features.d.ts +9 -0
  32. package/dist/v5/mesh-hierarchy.d.ts +47 -0
  33. package/dist/v5/mesh-source-features.d.ts +2 -1
  34. package/dist/v5/mesh-source-schema.d.ts +12 -0
  35. package/dist/v5/mesh-source-texture.d.ts +2 -0
  36. package/dist/v5/mesh-source.d.ts +13 -3
  37. package/dist/v5/mesh-tileset-sink.d.ts +5 -0
  38. package/dist/v5/mesh.d.ts +6 -1
  39. package/dist/v5/node-cli.d.ts +9 -0
  40. package/dist/v5/node-conversion.d.ts +32 -0
  41. package/dist/v5/node-feature-schema.d.ts +3 -0
  42. package/dist/v5/node-i3s-source.d.ts +41 -0
  43. package/dist/v5/node-source.d.ts +47 -0
  44. package/dist/v5/node.cjs +900 -0
  45. package/dist/v5/node.d.ts +6 -0
  46. package/dist/v5/node.js +877 -0
  47. package/dist/v5/point-cloud-file.d.ts +83 -0
  48. package/dist/v5/point-cloud-potree.d.ts +47 -0
  49. package/dist/v5/point-cloud-source-encoder.d.ts +4 -7
  50. package/dist/v5/point-cloud-spatial.d.ts +22 -0
  51. package/dist/v5/point-cloud-tileset-sink.d.ts +28 -0
  52. package/dist/v5/point-cloud-tileset.d.ts +44 -0
  53. package/dist/v5/point-cloud.d.ts +26 -1
  54. package/dist/v5/resource-fetcher.d.ts +18 -0
  55. package/dist/v5/resource-manifest.d.ts +10 -1
  56. package/dist/v5/selected-mesh-source.d.ts +53 -0
  57. package/dist/v5/spatial-conversion.d.ts +3 -1
  58. package/package.json +33 -25
  59. package/src/index.ts +4 -1
  60. package/src/v4/3d-tiles-converter/helpers/load-i3s.ts +2 -4
  61. package/src/v4/converter-cli.ts +8 -2
  62. package/src/v4/i3s-converter/helpers/load-3d-tiles.ts +3 -51
  63. package/src/v4/i3s-converter/helpers/node-index-document.ts +5 -2
  64. package/src/v4/i3s-converter/helpers/preprocess-3d-tiles.ts +1 -1
  65. package/src/v4/i3s-converter/json-templates/store.ts +2 -1
  66. package/src/v5/adapters.ts +69 -2
  67. package/src/v5/archive-source.ts +235 -0
  68. package/src/v5/browser-tileset-source.ts +418 -48
  69. package/src/v5/browser.ts +81 -2
  70. package/src/v5/conversion-api.ts +69 -9
  71. package/src/v5/converter-cli.ts +28 -0
  72. package/src/v5/core.ts +6 -0
  73. package/src/v5/i3s-mesh-conversion.ts +97 -19
  74. package/src/v5/i3s-mesh-sink.ts +351 -0
  75. package/src/v5/i3s-mesh-source-features.ts +279 -0
  76. package/src/v5/i3s-mesh-source-material.ts +157 -0
  77. package/src/v5/i3s-mesh-source.ts +228 -0
  78. package/src/v5/i3s-selection-source.ts +298 -0
  79. package/src/v5/index.ts +60 -2
  80. package/src/v5/mesh-conversion.ts +61 -11
  81. package/src/v5/mesh-draco.ts +47 -3
  82. package/src/v5/mesh-features.ts +319 -0
  83. package/src/v5/mesh-hierarchy.ts +648 -0
  84. package/src/v5/mesh-source-features.ts +73 -10
  85. package/src/v5/mesh-source-schema.ts +134 -0
  86. package/src/v5/mesh-source-texture.ts +47 -0
  87. package/src/v5/mesh-source.ts +99 -25
  88. package/src/v5/mesh-tileset-sink.ts +1 -1
  89. package/src/v5/mesh.ts +16 -7
  90. package/src/v5/node-cli.ts +197 -0
  91. package/src/v5/node-conversion.ts +345 -0
  92. package/src/v5/node-feature-schema.ts +155 -0
  93. package/src/v5/node-i3s-source.ts +181 -0
  94. package/src/v5/node-source.ts +328 -0
  95. package/src/v5/node.ts +16 -0
  96. package/src/v5/point-cloud-conversion.ts +9 -1
  97. package/src/v5/point-cloud-file.ts +306 -0
  98. package/src/v5/point-cloud-potree.ts +130 -0
  99. package/src/v5/point-cloud-source-encoder.ts +31 -20
  100. package/src/v5/point-cloud-spatial.ts +280 -0
  101. package/src/v5/point-cloud-tileset-sink.ts +234 -0
  102. package/src/v5/point-cloud-tileset.ts +137 -0
  103. package/src/v5/point-cloud.ts +159 -32
  104. package/src/v5/resource-fetcher.ts +113 -0
  105. package/src/v5/resource-manifest.ts +40 -5
  106. package/src/v5/selected-mesh-source.ts +384 -0
  107. package/src/v5/spatial-conversion.ts +161 -6
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  [loaders.gl](https://loaders.gl/docs) is a collection of framework independent 3D and geospatial parsers and encoders.
4
4
 
5
- This module contains command line scripts and JavaScript APIs for converting between formats, for instance betwen 3D Tiles and I3S tilesets.
5
+ This module contains command line scripts and JavaScript APIs for converting between formats, for instance between 3D Tiles and I3S tilesets.
6
6
 
7
7
  For documentation please visit the [website](https://loaders.gl).
8
8
 
@@ -23,7 +23,7 @@ The v5 implementation is split into two entrypoints inside this application:
23
23
 
24
24
  The existing `/v5` and `/v5/browser` imports remain compatible. The adapters consume the
25
25
  same core functions, types and error class. No implementation or dependencies move into
26
- other packages; CLI and v4 code are unchanged. Applications supply platform I/O adapters.
26
+ other packages. The original CLI and v4 code remain compatible. Node inspection now has a separate entrypoint and command, described below.
27
27
 
28
28
  ## V5 source-backed mesh traversal
29
29
 
@@ -475,3 +475,212 @@ error in the supplied budget. This sink does not infer source LOD relationships
475
475
  The [browser example](../../examples/website/i3s-slpk/README.md) demonstrates up to 64
476
476
  selected leaf contents, aggregate transport/decoded byte gates, download and incremental
477
477
  preview. SLPK still uses the single-mesh sink; multi-node I3S authoring is a separate increment.
478
+
479
+
480
+ ### Source CRS preparation
481
+
482
+ Both mesh codecs accept `createI3SConversionSpatialContext` for selected absolute I3S
483
+ geometry. Its `transformGeometryAsync` keeps positions in Float64 through unit, elevation,
484
+ and CRS operations before destination writers rebase to float32 and check precision.
485
+ Use the explicit I3S `normalReferenceFrame` when its vectors use a local ENU basis.
486
+
487
+ Point-source conversion accepts the same context as `spatialContext`. Cartesian affine
488
+ placement or longitude/latitude offsets are resolved before the CRS operation;
489
+ `getTileEncodingOptions` then receives the prepared target-frame tile for RTC selection.
490
+ The direct async `transformPointCloudSourceTile` helper supports separate preparation.
491
+ Source metadata must agree with the context. For already transformed ECEF content, a native
492
+ EPSG:4978 context can flatten renderer placement without repeating the source operation.
493
+ Ambiguous renderer coordinates fail explicitly. See the [v5 API guide](../../docs/modules/tile-converter/api-reference/v5-conversion.md)
494
+ for supported layouts, normal frames, and application-owned spatial resources.
495
+
496
+ ### Original I3S mesh input
497
+
498
+ The v5 adapters export `createI3SMeshTilesetConversionSource` for a selected
499
+ I3S mesh profile. Use a dedicated source-backed runtime with `i3s.geometryMode: 'source'`
500
+ to retain absolute Float64 source coordinates and original normals. Pair the GLB codec
501
+ with `autoOrigin: true` to choose the placement origin after spatial transformation.
502
+ One encoded PNG/JPEG base-color texture and explicit wrapping are preserved without decoding
503
+ pixels. `features` reads standard scalar/string attribute resources into a caller-declared Arrow
504
+ schema using an `objectIdProperty`, optional `sourceFeatureIdProperty` and `maxAttributeBytes`.
505
+ Signed/unsigned 64-bit properties retain exact bigint values; triangle ownership must be complete.
506
+ Supply `readExternalResource` for external textures/attributes, including byte limits, archive
507
+ resolution, authentication and decompression. `getFeatures` remains the custom alternative.
508
+ Unsupported atlas regions, colors, richer maps, domains/dates and layouts fail explicitly.
509
+ See the v5 conversion API reference for the exact source profile and an example mapping.
510
+ See the [v5 conversion reference](../../docs/modules/tile-converter/api-reference/v5-conversion.md).
511
+
512
+ ## Complete explicit mesh hierarchy
513
+
514
+ Opt in with `preserveHierarchy: true` on `convertNodeTileset`, or pair
515
+ `createSelectedMeshConversionSource` with `createMeshHierarchyTilesetSink` through the portable
516
+ adapters. The v5 CLI exposes `--preserve-hierarchy`. Select every inspected binary content.
517
+
518
+ The profile retains explicit topology, external document placements, parent content,
519
+ ADD/REPLACE refinement and version-aware metric errors for native ECEF 3D Tiles/3TZ output.
520
+ Static multi-primitive meshes and repeated scene placements become ordered GLBs on their
521
+ original tile; each retains its supported material, feature table and effective placement.
522
+ Output order follows source content slots, then scene traversal and primitive order.
523
+ Primitives share the first primitive’s origin on each tile and must meet the precision gate.
524
+ The sink requires ordered `contentPrimitive: {index, last}` descriptors through the mesh codec
525
+ before finalization. Outputs without a descriptor remain singleton contents.
526
+
527
+ Limits are 32 document placements, 256 tiles, 64 selected binary contents and 64 total primitive
528
+ placements, plus 16 MiB input and 32 MiB output/archive gates. These are not peak-memory bounds.
529
+ Implicit tiling, composites, GPU instancing, mixed external-document contents and I3S LOD
530
+ translation remain outside this profile. The browser example still exports flat partial
531
+ collections. See the [CLI guide](https://loaders.gl/docs/modules/tile-converter/cli-reference/tile-converter-v5)
532
+ and [conversion support](https://loaders.gl/docs/modules/tile-converter/cli-reference/supported-features).
533
+
534
+ ## Experimental Node inspection
535
+
536
+ `tile-converter-v5 inspect` inventories metadata and ordered content declarations from an
537
+ explicit 3D Tiles 1.0/1.1 JSON path or HTTP(S) URL, or a local 3TZ archive:
538
+
539
+ ```sh
540
+ tile-converter-v5 inspect ./dataset/tileset.json
541
+ tile-converter-v5 inspect ./dataset.3tz --input-format 3tz
542
+ ```
543
+
544
+ The command prints JSON to stdout, emits JSON errors to stderr and exits nonzero on failure.
545
+ It reads metadata without opening tile payloads. The default budgets are 16 MiB and 1,000
546
+ content placements; `--max-input-bytes` and `--max-resources` can lower them. This command
547
+ does not perform conversion or full-content validation.
548
+
549
+ `createNodeTilesetConversionSource` from `@loaders.gl/tile-converter/v5/node` also supplies
550
+ bounded typed-array raw reads for application codecs. It reuses portable explicit traversal.
551
+ Local files are confined to the root document's real directory, including symlink resolution;
552
+ 3TZ reads load the index once and stay inside the archive. Close the dedicated source in
553
+ `finally`. Portable entrypoints do not import this Node adapter. I3S/SLPK, remote archives,
554
+ output sinks, nested/implicit dataset extraction and installed Windows qualification remain
555
+ follow-ups. Inputs must remain unchanged during a source's lifetime.
556
+
557
+ ## Decoded point-cloud authoring
558
+
559
+ `convertPointCloudToTileset` connects the dynamic point tiler to the v5 PNTS sink. It accepts one
560
+ loader-produced point `Mesh` or `MeshArrowTable` and emits every input row once across a flat,
561
+ additive 3D Tiles 1.0 collection. Supply explicit native ECEF (EPSG:4978 XYZ meters with ellipsoidal
562
+ heights); the helper does not infer or transform a CRS. Per-tile RTC centers retain small offsets at
563
+ ECEF magnitudes, and `geometricError` must cover measured position reconstruction error.
564
+
565
+ ```ts
566
+ import {createTilesetSpatialReference} from '@loaders.gl/tiles';
567
+ import {convertPointCloudToTileset} from '@loaders.gl/tile-converter/v5/browser';
568
+
569
+ const result = await convertPointCloudToTileset(decodedPoints, {
570
+ spatialReference: createTilesetSpatialReference({
571
+ sourceCrs: 'EPSG:4978',
572
+ heightReference: 'ellipsoidal',
573
+ coordinateFrame: 'geocentric',
574
+ axisOrder: 'xyz'
575
+ }),
576
+ geometricError: 0.001,
577
+ maxTiles: 1000,
578
+ maxTotalBytes: 64 * 1024 * 1024,
579
+ tiling: {
580
+ maxInputBytes: 64 * 1024 * 1024,
581
+ maxIndexBytes: 16 * 1024 * 1024,
582
+ maxTileBytes: 4 * 1024 * 1024,
583
+ maxNodes: 1000
584
+ },
585
+ archive: {maxArchiveBytes: 80 * 1024 * 1024},
586
+ signal: abortController.signal
587
+ });
588
+ // result.files contains named PNTS Blobs and tileset.json.
589
+ // result.archive is an indexed 3TZ Blob; saving and object URLs belong to the application.
590
+ ```
591
+
592
+ Omit `archive` for files only. Indexing, traversal and packaging use the same cancellation signal;
593
+ the helper closes its private source on success and failure and returns no partial package.
594
+ The report counts PNTS outputs and gathered Arrow input column buffers. Tileset JSON is included in
595
+ `maxTotalBytes`; ZIP headers and index are included in `maxArchiveBytes`. These are separate bounds,
596
+ not a total heap cap. Arrow normalization, source buffers, row indexes, gathered tiles and ZIP
597
+ serialization can occupy additional memory. Input must remain immutable until the promise settles.
598
+
599
+ The first authoring profile is in memory and preserves all rows, including terminal-node overflow.
600
+ It flattens the octree into independent tile placements; it does not preserve octree LOD, provide
601
+ sampling-error guarantees, ingest batches, or author I3S point layers. PNTS supports `POSITION`,
602
+ `NORMAL`, `BATCH_ID` and one color attribute. Other attributes fail instead of being silently dropped;
603
+ explicitly map or remove them before authoring. LAS, COPC, Potree and other loaders may produce
604
+ compatible decoded points, but their native CRS and additional attributes still require preparation.
605
+
606
+ ### Point-cloud files and harvested mesh vertices
607
+
608
+ COPC is already a self-contained, range-readable `.copc.laz` file. Potree datasets
609
+ contain multiple files. `encodePotreeArchive` packages the complete output of
610
+ `encodePotreeDataset` into a deterministic STORE ZIP32 with metadata at the root.
611
+ This **loaders.gl Potree ZIP convention is not a native Potree archive standard**.
612
+ The original relative paths are preserved; extracted files remain an ordinary
613
+ Potree dataset. The writer supports its existing 1.0–1.8 and 2.0 DEFAULT profiles.
614
+
615
+ ```ts
616
+ import {
617
+ encodePotreeArchive,
618
+ openPointCloudFile,
619
+ extractMeshVertices
620
+ } from '@loaders.gl/tile-converter/v5/browser';
621
+ import {COPCWriter} from '@loaders.gl/copc';
622
+
623
+ // Opt in to one point per stored vertex of already placed triangle geometry.
624
+ const points = extractMeshVertices(meshResource.mesh, {
625
+ attributes: [], // Select additional destination-compatible attributes explicitly.
626
+ maxPoints: 100000
627
+ });
628
+ const potreeZip = await encodePotreeArchive(points, {
629
+ maxArchiveBytes: 32 * 1024 * 1024,
630
+ potree: {
631
+ version: '2.0',
632
+ projection: 'EPSG:4978',
633
+ scale: [0.001, 0.001, 0.001],
634
+ maxPositionError: 0.001,
635
+ maxOutputBytes: 16 * 1024 * 1024
636
+ }
637
+ });
638
+
639
+ // The existing COPC writer produces a native single-file destination.
640
+ // Supply a bounded decoded batch, compatible attributes, and an explicit CRS.
641
+ const copcFile = new Blob([COPCWriter.encodeSync(points, {
642
+ copc: {scale: [0.001, 0.001, 0.001], offset: [0, 0, 0], colorDepth: 8, wkt: ecefWkt}
643
+ })], {type: 'application/octet-stream'});
644
+
645
+ const opened = await openPointCloudFile(potreeZip, {
646
+ format: 'potree-zip', // Use 'copc' for copcFile or a dropped COPC File.
647
+ maxFileBytes: 32 * 1024 * 1024,
648
+ maxEntries: 1000,
649
+ maxResourceBytes: 4 * 1024 * 1024
650
+ });
651
+ try {
652
+ const root = await opened.source.getRootTile();
653
+ const content = await opened.source.loadTileContent(root);
654
+ // Traverse children on demand with the existing source APIs.
655
+ } finally {
656
+ await opened.close();
657
+ }
658
+ ```
659
+
660
+ Modern Potree ZIP node reads slice archived ranges without reading all of
661
+ `octree.bin`. Readers use the shared ZIP32/ZIP64 validator and accept unencrypted STORE entries,
662
+ including data descriptors and comments, with canonical relative ASCII resource paths. DEFLATE
663
+ bundles are rejected. Complete reads validate ZIP CRCs; partial ranges cannot. Root `metadata.json` or `cloud.js` is selected only when
664
+ unambiguous; supply `metadataPath` for a nested dataset. Partial range reads do
665
+ not validate whole-entry ZIP CRCs. The isolated archive transport never falls
666
+ back to a network request.
667
+
668
+ Mesh harvesting preserves repeated/coincident stored vertices, ignores indices,
669
+ and does not sample triangle surfaces. Selected attributes share the caller's
670
+ immutable buffers. Unselected attributes, materials and feature associations are
671
+ intentionally omitted. Use a mesh source adapter first to apply glTF node,
672
+ up-axis, RTC and tile placement once; harvesting performs no coordinate math.
673
+ Callers choose source tiles and LOD: collecting every mesh LOD can repeat the
674
+ same geometry, and harvesting does not deduplicate across resources.
675
+
676
+ Sources retain their current coordinate policies: Potree 2.0 returns native
677
+ positions, legacy Potree keeps its projection behavior, and COPC can return
678
+ positions relative to an origin. Apply the declared origin and explicit CRS
679
+ operation before writing absolute points into another format. Attribute mapping,
680
+ LOD sampling and independent viewer qualification remain separate work.
681
+
682
+ Potree output, final ZIP size, entry count, input file size and individual range
683
+ limits are separate bounds. They do not bound total heap, COPC decompression or
684
+ COPC writer temporaries. Potree authoring and COPC writing operate on decoded
685
+ in-memory inputs; these APIs do not assemble a large source into one output
686
+ out of core. Applications own downloading Blobs and revoking object URLs.
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ import '../dist/v5/converter-cli.js';