@playcanvas/splat-transform 1.1.0 → 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.
package/dist/cli.mjs CHANGED
@@ -13472,24 +13472,75 @@ const readSpz = async (source) => {
13472
13472
 
13473
13473
  /**
13474
13474
  * Default logger implementation (browser-safe).
13475
- * Progress is a no-op since process.stdout is not available in browsers.
13476
13475
  */
13477
13476
  const defaultLogger = {
13478
13477
  log: (...args) => console.log(...args),
13479
13478
  warn: (...args) => console.warn(...args),
13480
13479
  error: (...args) => console.error(...args),
13481
13480
  debug: (...args) => console.log(...args),
13482
- progress: () => { },
13483
- output: text => console.log(text)
13481
+ output: text => console.log(text),
13482
+ onProgress: (node) => {
13483
+ // step 0 is the begin notification - nothing to print
13484
+ if (node.step === 0)
13485
+ return;
13486
+ const indent = ' '.repeat(node.depth);
13487
+ const name = node.stepName ?? '';
13488
+ console.log(`${indent}[${node.step}/${node.totalSteps}] ${name}`);
13489
+ }
13484
13490
  };
13485
13491
  let impl = defaultLogger;
13486
13492
  let quiet = false;
13493
+ /**
13494
+ * Progress tracking with nested step support.
13495
+ * Access via logger.progress.begin(), logger.progress.step()
13496
+ */
13497
+ class Progress {
13498
+ currentNode;
13499
+ /**
13500
+ * Start a multi-step progress operation. Creates a new node with current as parent.
13501
+ * Calls onProgress with step: 0 to notify consumers of the new progress block.
13502
+ * @param totalSteps - Total number of steps in the operation.
13503
+ */
13504
+ begin(totalSteps) {
13505
+ this.currentNode = {
13506
+ step: 0,
13507
+ totalSteps,
13508
+ stepName: undefined,
13509
+ parent: this.currentNode,
13510
+ depth: (this.currentNode?.depth ?? -1) + 1
13511
+ };
13512
+ if (!quiet)
13513
+ impl.onProgress(this.currentNode);
13514
+ }
13515
+ /**
13516
+ * Advance to the next step. Auto-increments the step counter.
13517
+ * Auto-ends when all steps are complete.
13518
+ * @param name - Optional name of the step.
13519
+ */
13520
+ step(name) {
13521
+ if (!this.currentNode)
13522
+ return;
13523
+ this.currentNode.step++;
13524
+ this.currentNode.stepName = name;
13525
+ if (!quiet)
13526
+ impl.onProgress(this.currentNode);
13527
+ // Auto-end when all steps complete
13528
+ if (this.currentNode.step === this.currentNode.totalSteps) {
13529
+ this.currentNode = this.currentNode.parent;
13530
+ }
13531
+ }
13532
+ }
13487
13533
  /**
13488
13534
  * Global logger instance with injectable implementation.
13489
13535
  * Use setLogger() to provide a custom implementation (e.g., Node.js with process.stdout).
13490
13536
  * Use setQuiet() to suppress log/warn/progress output.
13491
13537
  */
13492
13538
  const logger = {
13539
+ /**
13540
+ * Progress tracking with nested step support.
13541
+ * Call begin(n) to start, then step() n times. Auto-ends when complete.
13542
+ */
13543
+ progress: new Progress(),
13493
13544
  /**
13494
13545
  * Set a custom logger implementation.
13495
13546
  * @param l - The logger implementation to use.
@@ -13535,14 +13586,6 @@ const logger = {
13535
13586
  if (!quiet)
13536
13587
  impl.debug(...args);
13537
13588
  },
13538
- /**
13539
- * Output text without newline (for progress indicators). Suppressed in quiet mode.
13540
- * @param text - The text to output.
13541
- */
13542
- progress(text) {
13543
- if (!quiet)
13544
- impl.progress(text);
13545
- },
13546
13589
  /**
13547
13590
  * Output data to stdout (for piping). Always shown, even in quiet mode.
13548
13591
  * @param text - The text to output.
@@ -13808,7 +13851,7 @@ class CompressedChunk {
13808
13851
  }
13809
13852
  }
13810
13853
 
13811
- var version = "1.1.0";
13854
+ var version = "1.2.0";
13812
13855
 
13813
13856
  // sort the provided indices into morton order
13814
13857
  const sortMortonOrder = (dataTable, indices) => {
@@ -14665,6 +14708,8 @@ const kmeans = async (points, k, iterations, device) => {
14665
14708
  let converged = false;
14666
14709
  let steps = 0;
14667
14710
  logger.debug(`Running k-means clustering: dims=${points.numColumns} points=${points.numRows} clusters=${k} iterations=${iterations}...`);
14711
+ // Report iterations as anonymous nested steps
14712
+ logger.progress.begin(iterations);
14668
14713
  while (!converged) {
14669
14714
  if (gpuClustering) {
14670
14715
  await gpuClustering.execute(points, centroids, labels);
@@ -14690,12 +14735,12 @@ const kmeans = async (points, k, iterations, device) => {
14690
14735
  if (steps >= iterations) {
14691
14736
  converged = true;
14692
14737
  }
14693
- logger.progress('#');
14738
+ // Report iteration as anonymous step
14739
+ logger.progress.step();
14694
14740
  }
14695
14741
  if (gpuClustering) {
14696
14742
  gpuClustering.destroy();
14697
14743
  }
14698
- logger.debug(' done 🎉');
14699
14744
  return { centroids, labels };
14700
14745
  };
14701
14746
 
@@ -14963,12 +15008,25 @@ const writeSog = async (options, fs) => {
14963
15008
  };
14964
15009
  };
14965
15010
  const shBands = { '9': 1, '24': 2, '-1': 3 }[shNames$1.findIndex(v => !dataTable.hasColumn(v))] ?? 0;
15011
+ const totalSteps = shBands > 0 ? 7 : 6;
14966
15012
  // convert and write attributes
15013
+ logger.progress.begin(totalSteps);
15014
+ logger.progress.step('Generating morton order');
15015
+ // indices already generated above
15016
+ logger.progress.step('Writing positions');
14967
15017
  const meansMinMax = await writeMeans();
15018
+ logger.progress.step('Writing quaternions');
14968
15019
  await writeQuaternions();
15020
+ logger.progress.step('Compressing scales');
14969
15021
  const scalesCodebook = await writeScales();
15022
+ logger.progress.step('Compressing colors');
14970
15023
  const colorsCodebook = await writeColors();
14971
- const shN = shBands > 0 ? await writeSH(shBands) : null;
15024
+ let shN = null;
15025
+ if (shBands > 0) {
15026
+ logger.progress.step('Compressing spherical harmonics');
15027
+ shN = await writeSH(shBands);
15028
+ }
15029
+ logger.progress.step('Finalizing');
14972
15030
  // construct meta.json
14973
15031
  const meta = {
14974
15032
  version: 2,
@@ -16332,7 +16390,7 @@ SUPPORTED INPUTS
16332
16390
  .ply .compressed.ply .sog meta.json .ksplat .splat .spz .mjs .lcc
16333
16391
 
16334
16392
  SUPPORTED OUTPUTS
16335
- .ply .compressed.ply .sog meta.json .csv .html null
16393
+ .ply .compressed.ply .sog meta.json lod-meta.json .csv .html null
16336
16394
 
16337
16395
  ACTIONS (can be repeated, in any order)
16338
16396
  -t, --translate <x,y,z> Translate Gaussians by (x, y, z)
@@ -16394,8 +16452,15 @@ const main = async () => {
16394
16452
  warn: (...args) => console.warn(...args),
16395
16453
  error: (...args) => console.error(...args),
16396
16454
  debug: (...args) => console.error(...args),
16397
- progress: text => process.stderr.write(text),
16398
- output: text => console.log(text)
16455
+ output: text => console.log(text),
16456
+ onProgress: (node) => {
16457
+ if (node.stepName) {
16458
+ console.error(`[${node.step}/${node.totalSteps}] ${node.stepName}`);
16459
+ }
16460
+ else if (node.step > 0) {
16461
+ process.stderr.write(node.step === node.totalSteps ? '# done 🎉\n' : '#');
16462
+ }
16463
+ }
16399
16464
  });
16400
16465
  // configure logger
16401
16466
  logger.setQuiet(options.quiet);