simview 6.1.1__tar.gz → 6.1.2__tar.gz

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 (105) hide show
  1. {simview-6.1.1/simview.egg-info → simview-6.1.2}/PKG-INFO +1 -1
  2. {simview-6.1.1 → simview-6.1.2}/pyproject.toml +1 -1
  3. {simview-6.1.1 → simview-6.1.2}/simview/static/js/SimView.js +7 -2
  4. {simview-6.1.1 → simview-6.1.2}/simview/static/js/components/BatchManager.js +14 -6
  5. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/ScalarPlotter.js +20 -41
  6. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/chartControls.js +15 -0
  7. {simview-6.1.1 → simview-6.1.2/simview.egg-info}/PKG-INFO +1 -1
  8. {simview-6.1.1 → simview-6.1.2}/LICENSE +0 -0
  9. {simview-6.1.1 → simview-6.1.2}/MANIFEST.in +0 -0
  10. {simview-6.1.1 → simview-6.1.2}/README.md +0 -0
  11. {simview-6.1.1 → simview-6.1.2}/setup.cfg +0 -0
  12. {simview-6.1.1 → simview-6.1.2}/simview/__init__.py +0 -0
  13. {simview-6.1.1 → simview-6.1.2}/simview/__main__.py +0 -0
  14. {simview-6.1.1 → simview-6.1.2}/simview/columnar.py +0 -0
  15. {simview-6.1.1 → simview-6.1.2}/simview/diff.py +0 -0
  16. {simview-6.1.1 → simview-6.1.2}/simview/info.py +0 -0
  17. {simview-6.1.1 → simview-6.1.2}/simview/launcher.py +0 -0
  18. {simview-6.1.1 → simview-6.1.2}/simview/live.py +0 -0
  19. {simview-6.1.1 → simview-6.1.2}/simview/merge.py +0 -0
  20. {simview-6.1.1 → simview-6.1.2}/simview/model.py +0 -0
  21. {simview-6.1.1 → simview-6.1.2}/simview/py.typed +0 -0
  22. {simview-6.1.1 → simview-6.1.2}/simview/remote.py +0 -0
  23. {simview-6.1.1 → simview-6.1.2}/simview/render.py +0 -0
  24. {simview-6.1.1 → simview-6.1.2}/simview/scene.py +0 -0
  25. {simview-6.1.1 → simview-6.1.2}/simview/server.py +0 -0
  26. {simview-6.1.1 → simview-6.1.2}/simview/state.py +0 -0
  27. {simview-6.1.1 → simview-6.1.2}/simview/static/css/controls.css +0 -0
  28. {simview-6.1.1 → simview-6.1.2}/simview/static/js/components/AnimationController.js +0 -0
  29. {simview-6.1.1 → simview-6.1.2}/simview/static/js/components/InteractionController.js +0 -0
  30. {simview-6.1.1 → simview-6.1.2}/simview/static/js/components/Scene.js +0 -0
  31. {simview-6.1.1 → simview-6.1.2}/simview/static/js/components/StateStore.js +0 -0
  32. {simview-6.1.1 → simview-6.1.2}/simview/static/js/components/WindowedField.js +0 -0
  33. {simview-6.1.1 → simview-6.1.2}/simview/static/js/config.js +0 -0
  34. {simview-6.1.1 → simview-6.1.2}/simview/static/js/main.js +0 -0
  35. {simview-6.1.1 → simview-6.1.2}/simview/static/js/objects/Body.js +0 -0
  36. {simview-6.1.1 → simview-6.1.2}/simview/static/js/objects/StaticObject.js +0 -0
  37. {simview-6.1.1 → simview-6.1.2}/simview/static/js/objects/Terrain.js +0 -0
  38. {simview-6.1.1 → simview-6.1.2}/simview/static/js/objects/colormap.js +0 -0
  39. {simview-6.1.1 → simview-6.1.2}/simview/static/js/objects/similarity.js +0 -0
  40. {simview-6.1.1 → simview-6.1.2}/simview/static/js/objects/utils.js +0 -0
  41. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/AnalysisPanel.js +0 -0
  42. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/BatchLegend.js +0 -0
  43. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/BodyStateWindow.js +0 -0
  44. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/Controls.js +0 -0
  45. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/ErrorMetrics.js +0 -0
  46. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/Legend.js +0 -0
  47. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/PlaybackControls.js +0 -0
  48. {simview-6.1.1 → simview-6.1.2}/simview/static/js/ui/TerrainProfile.js +0 -0
  49. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/batchPresets.js +0 -0
  50. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/batchVisibility.js +0 -0
  51. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/blobCodec.js +0 -0
  52. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/blobWindow.js +0 -0
  53. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/bodyTransforms.js +0 -0
  54. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/cameraRange.js +0 -0
  55. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/csv.js +0 -0
  56. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/episodes.js +0 -0
  57. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/errorMath.js +0 -0
  58. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/interpolate.js +0 -0
  59. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/keyboard.js +0 -0
  60. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/liveFollow.js +0 -0
  61. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/terrainSample.js +0 -0
  62. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/uplot.js +0 -0
  63. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/viewState.js +0 -0
  64. {simview-6.1.1 → simview-6.1.2}/simview/static/js/utils/viewerDefaults.js +0 -0
  65. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/js-colormaps.js +0 -0
  66. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +0 -0
  67. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +0 -0
  68. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/three-0.174.0/three.core.js +0 -0
  69. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/three-0.174.0/three.module.js +0 -0
  70. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/uPlot.esm.js +0 -0
  71. {simview-6.1.1 → simview-6.1.2}/simview/static/lib/uPlot.min.css +0 -0
  72. {simview-6.1.1 → simview-6.1.2}/simview/static/textures/contacts/red-cross0.png +0 -0
  73. {simview-6.1.1 → simview-6.1.2}/simview/static/textures/points/ball1.png +0 -0
  74. {simview-6.1.1 → simview-6.1.2}/simview/templates/index.html +0 -0
  75. {simview-6.1.1 → simview-6.1.2}/simview/terrain.py +0 -0
  76. {simview-6.1.1 → simview-6.1.2}/simview/utils.py +0 -0
  77. {simview-6.1.1 → simview-6.1.2}/simview/view.py +0 -0
  78. {simview-6.1.1 → simview-6.1.2}/simview.egg-info/SOURCES.txt +0 -0
  79. {simview-6.1.1 → simview-6.1.2}/simview.egg-info/dependency_links.txt +0 -0
  80. {simview-6.1.1 → simview-6.1.2}/simview.egg-info/entry_points.txt +0 -0
  81. {simview-6.1.1 → simview-6.1.2}/simview.egg-info/requires.txt +0 -0
  82. {simview-6.1.1 → simview-6.1.2}/simview.egg-info/top_level.txt +0 -0
  83. {simview-6.1.1 → simview-6.1.2}/tests/test_batch_selection.py +0 -0
  84. {simview-6.1.1 → simview-6.1.2}/tests/test_cli.py +0 -0
  85. {simview-6.1.1 → simview-6.1.2}/tests/test_columnar_ondisk.py +0 -0
  86. {simview-6.1.1 → simview-6.1.2}/tests/test_columnar_states.py +0 -0
  87. {simview-6.1.1 → simview-6.1.2}/tests/test_contacts.py +0 -0
  88. {simview-6.1.1 → simview-6.1.2}/tests/test_diff.py +0 -0
  89. {simview-6.1.1 → simview-6.1.2}/tests/test_embed_defaults.py +0 -0
  90. {simview-6.1.1 → simview-6.1.2}/tests/test_episodes.py +0 -0
  91. {simview-6.1.1 → simview-6.1.2}/tests/test_info.py +0 -0
  92. {simview-6.1.1 → simview-6.1.2}/tests/test_launcher.py +0 -0
  93. {simview-6.1.1 → simview-6.1.2}/tests/test_live.py +0 -0
  94. {simview-6.1.1 → simview-6.1.2}/tests/test_merge.py +0 -0
  95. {simview-6.1.1 → simview-6.1.2}/tests/test_pointcloud_features.py +0 -0
  96. {simview-6.1.1 → simview-6.1.2}/tests/test_remote.py +0 -0
  97. {simview-6.1.1 → simview-6.1.2}/tests/test_roundtrip.py +0 -0
  98. {simview-6.1.1 → simview-6.1.2}/tests/test_scene.py +0 -0
  99. {simview-6.1.1 → simview-6.1.2}/tests/test_server.py +0 -0
  100. {simview-6.1.1 → simview-6.1.2}/tests/test_show.py +0 -0
  101. {simview-6.1.1 → simview-6.1.2}/tests/test_terrain.py +0 -0
  102. {simview-6.1.1 → simview-6.1.2}/tests/test_terrain_query.py +0 -0
  103. {simview-6.1.1 → simview-6.1.2}/tests/test_trajectory.py +0 -0
  104. {simview-6.1.1 → simview-6.1.2}/tests/test_utils.py +0 -0
  105. {simview-6.1.1 → simview-6.1.2}/tests/test_view.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simview
3
- Version: 6.1.1
3
+ Version: 6.1.2
4
4
  Summary: THREE.js-based simulation visualization tool
5
5
  Author-email: Jan Vlk <vlkjan6@fel.cvut.cz>, Ales Kucera <kuceral4@fel.cvut.cz>, David Korcak <david.korcak@gmail.com>
6
6
  License-Expression: BSD-3-Clause
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simview"
7
- version = "6.1.1"
7
+ version = "6.1.2"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.12"
10
10
  license = "BSD-3-Clause"
@@ -757,8 +757,11 @@ export class SimView {
757
757
  const currentBodyPos = new THREE.Vector3(pos.x + offset.x, pos.y + offset.y, pos.z + offset.z);
758
758
 
759
759
  try {
760
- if (this._lastTrackedBody !== this.uiState.trackBody) {
761
- // On first tracking or switch, center the target on the body, preserving the viewing angle
760
+ if (
761
+ this._lastTrackedBody !== this.uiState.trackBody ||
762
+ this._lastTrackedBatch !== activeBatch
763
+ ) {
764
+ // On first tracking or a body/batch switch, center the target on the body, preserving the viewing angle
762
765
  const delta = currentBodyPos.clone().sub(this.scene.controls.target);
763
766
  this.scene.camera.position.add(delta);
764
767
  this.scene.controls.target.copy(currentBodyPos);
@@ -779,11 +782,13 @@ export class SimView {
779
782
  }
780
783
 
781
784
  this._lastTrackedBody = this.uiState.trackBody;
785
+ this._lastTrackedBatch = activeBatch;
782
786
  this._lastTrackedPosition = currentBodyPos.clone();
783
787
  }
784
788
  }
785
789
  } else {
786
790
  this._lastTrackedBody = null;
791
+ this._lastTrackedBatch = null;
787
792
  this._lastTrackedPosition = null;
788
793
  }
789
794
  this.scene.animate(now);
@@ -152,12 +152,19 @@ export class BatchManager {
152
152
  return { x: 0, y: 0, z: 0 };
153
153
  }
154
154
 
155
- changeFocusOnBatchByIndex(batchIndex) {
155
+ // Moves camera and target by the offset between the two batches' grid
156
+ // cells, so the view keeps its place relative to the scene. Snapping the
157
+ // target to the cell origin instead lost the view on every chart click
158
+ // (which re-selects the closest batch) and broke body tracking.
159
+ changeFocusOnBatchByIndex(batchIndex, fromBatchIndex) {
156
160
  const { camera, controls } = this.app.scene;
157
- const { x, y, z } = this.getBatchOffset(batchIndex);
158
- const newCameraTarget = new THREE.Vector3(x, y, z);
159
- camera.position.add(newCameraTarget.clone().sub(controls.target));
160
- controls.target = newCameraTarget;
161
+ const to = this.getBatchOffset(batchIndex);
162
+ const from = this.getBatchOffset(fromBatchIndex);
163
+ const shift = new THREE.Vector3(to.x - from.x, to.y - from.y, to.z - from.z);
164
+ if (shift.lengthSq() === 0) return;
165
+ camera.position.add(shift);
166
+ controls.target.add(shift);
167
+ controls.update();
161
168
  }
162
169
 
163
170
  setActiveBatch(batchIndex) {
@@ -167,8 +174,9 @@ export class BatchManager {
167
174
  console.warn("Invalid batch index:", batchIndex);
168
175
  return;
169
176
  }
177
+ const previousBatch = this.currentlyActiveBatch;
170
178
  this.currentlyActiveBatch = batchIndex;
171
- this.changeFocusOnBatchByIndex(batchIndex);
179
+ this.changeFocusOnBatchByIndex(batchIndex, previousBatch);
172
180
  // In focused mode the newly-active batch is (probably) not the one
173
181
  // currently built/drawn, so refresh before the panels read from it.
174
182
  this._recomputeVisibleBatches();
@@ -7,7 +7,7 @@ import {
7
7
  normalizeEpisodes,
8
8
  } from "../utils/episodes.js";
9
9
  import { makeChart, yIncrements } from "../utils/uplot.js";
10
- import { batchColumnsCsv, closestSeries, exportBar } from "./chartControls.js";
10
+ import { batchColumnsCsv, closestSeries, exportBar, finiteBounds } from "./chartControls.js";
11
11
 
12
12
  export class ScalarPlotter {
13
13
  constructor(app, scalarNames) {
@@ -35,7 +35,7 @@ export class ScalarPlotter {
35
35
  // {scalarName -> per-batch array of per-episode aggregates}, rebuilt
36
36
  // only when the episodes or the underlying series change.
37
37
  this.episodeAggregateCache = new Map();
38
- this.seriesRenderCallback = null;
38
+ this.markerDirty = false;
39
39
  this.opacityRenderCallback = null;
40
40
  this.minRenderDelay = 1000 / FREQ_CONFIG.scalarPlotter;
41
41
  this.lastRenderTime = Number.NEGATIVE_INFINITY;
@@ -140,16 +140,7 @@ export class ScalarPlotter {
140
140
  // scalar as one whole-trajectory Float32Array.
141
141
  const series = store.getScalarSeries(scalarName, batchSize);
142
142
  this.scalarSeries.set(scalarName, series);
143
-
144
- let min = Number.MAX_VALUE;
145
- let max = Number.MIN_VALUE;
146
- for (const batchSeries of series) {
147
- for (const { y } of batchSeries) {
148
- min = Math.min(min, y);
149
- max = Math.max(max, y);
150
- }
151
- }
152
- this.scalarBounds.set(scalarName, [min, max]);
143
+ this.scalarBounds.set(scalarName, finiteBounds(series));
153
144
  }
154
145
 
155
146
  this._initializePlots();
@@ -314,6 +305,7 @@ export class ScalarPlotter {
314
305
  },
315
306
  ],
316
307
  tooltip: (u, idx) => this._tooltipHtml(u, idx, name),
308
+ markerTime: () => this.times[this.currentEndIndex] ?? null,
317
309
  hooks: {
318
310
  draw: [
319
311
  (u) => {
@@ -331,7 +323,16 @@ export class ScalarPlotter {
331
323
  }
332
324
  },
333
325
  },
334
- [[], ...new Array(this.app.batchManager.simBatches).fill([])],
326
+ // The whole timeline, plotted once; playback only moves the
327
+ // marker. NaN (a gap in the source) becomes null, uPlot's gap.
328
+ [
329
+ this.times,
330
+ ...this.scalarSeries
331
+ .get(name)
332
+ .map((batchSeries) =>
333
+ batchSeries.map(({ y }) => (Number.isFinite(y) ? y : null))
334
+ ),
335
+ ],
335
336
  this.app
336
337
  );
337
338
 
@@ -365,27 +366,7 @@ export class ScalarPlotter {
365
366
  return;
366
367
  }
367
368
  this.currentEndIndex = newEndIndex;
368
- const activeChart = this.charts.get(this.activeScalar);
369
- if (!activeChart) {
370
- console.warn(`No chart found for scalar "${this.activeScalar}".`);
371
- return;
372
- }
373
-
374
- const scalarData = this.scalarSeries.get(this.activeScalar);
375
- if (!scalarData) {
376
- console.warn(`No data points found for scalar "${this.activeScalar}".`);
377
- return;
378
- }
379
-
380
- this.seriesRenderCallback = () => {
381
- const numPoints = this.currentEndIndex + 1;
382
- const xValues = this.times.slice(0, numPoints);
383
- const data = [xValues];
384
- for (let i = 0; i < this.app.batchManager.simBatches; i++) {
385
- data.push(scalarData[i].slice(0, numPoints).map((p) => p.y));
386
- }
387
- activeChart.setData(data, false);
388
- };
369
+ this.markerDirty = true;
389
370
  }
390
371
 
391
372
  setFocusedBatch(batchIndex, force = false) {
@@ -437,9 +418,8 @@ export class ScalarPlotter {
437
418
  }
438
419
 
439
420
  var needRender = false;
440
- if (this.seriesRenderCallback) {
441
- this.seriesRenderCallback();
442
- this.seriesRenderCallback = null;
421
+ if (this.markerDirty) {
422
+ this.markerDirty = false;
443
423
  needRender = true;
444
424
  }
445
425
  if (this.opacityRenderCallback) {
@@ -449,10 +429,9 @@ export class ScalarPlotter {
449
429
  }
450
430
 
451
431
  if (!needRender) return;
452
- // rebuildPaths must be true: the series data changes on every frame of
453
- // playback, and redrawing without rebuilding just repaints the paths
454
- // built for whatever data the chart first saw.
455
- activeChart.redraw(true, true);
432
+ // The data never changes after init, so the cached paths stay valid;
433
+ // strokes (focus opacity) are re-read on every draw anyway.
434
+ activeChart.redraw(false);
456
435
  }
457
436
 
458
437
  animate(now) {
@@ -20,6 +20,21 @@ export function closestSeries(u, dataIdx, yVal) {
20
20
  return best;
21
21
  }
22
22
 
23
+ // [min, max] over the finite y of every batch's {x, y} points; [0, 1] when
24
+ // there are none, so a chart never gets NaN/Infinity bounds.
25
+ export function finiteBounds(seriesPerBatch) {
26
+ let min = Infinity;
27
+ let max = -Infinity;
28
+ for (const batchSeries of seriesPerBatch) {
29
+ for (const { y } of batchSeries) {
30
+ if (!Number.isFinite(y)) continue;
31
+ if (y < min) min = y;
32
+ if (y > max) max = y;
33
+ }
34
+ }
35
+ return min <= max ? [min, max] : [0, 1];
36
+ }
37
+
23
38
  // CSV with a time column, then one column per batch (named after the batch's
24
39
  // display name); `seriesPerBatch[b][i]` is an {x, y} point or missing.
25
40
  export function batchColumnsCsv(batchManager, times, seriesPerBatch) {
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simview
3
- Version: 6.1.1
3
+ Version: 6.1.2
4
4
  Summary: THREE.js-based simulation visualization tool
5
5
  Author-email: Jan Vlk <vlkjan6@fel.cvut.cz>, Ales Kucera <kuceral4@fel.cvut.cz>, David Korcak <david.korcak@gmail.com>
6
6
  License-Expression: BSD-3-Clause
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes