simview 6.1.0__tar.gz → 6.1.1__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.0/simview.egg-info → simview-6.1.1}/PKG-INFO +1 -1
  2. {simview-6.1.0 → simview-6.1.1}/pyproject.toml +1 -1
  3. {simview-6.1.0 → simview-6.1.1}/simview/static/js/SimView.js +7 -0
  4. {simview-6.1.0 → simview-6.1.1}/simview/static/js/components/AnimationController.js +4 -0
  5. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/Controls.js +15 -0
  6. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/ScalarPlotter.js +1 -0
  7. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/viewState.js +29 -5
  8. {simview-6.1.0 → simview-6.1.1}/simview/view.py +17 -0
  9. {simview-6.1.0 → simview-6.1.1/simview.egg-info}/PKG-INFO +1 -1
  10. {simview-6.1.0 → simview-6.1.1}/tests/test_view.py +7 -0
  11. {simview-6.1.0 → simview-6.1.1}/LICENSE +0 -0
  12. {simview-6.1.0 → simview-6.1.1}/MANIFEST.in +0 -0
  13. {simview-6.1.0 → simview-6.1.1}/README.md +0 -0
  14. {simview-6.1.0 → simview-6.1.1}/setup.cfg +0 -0
  15. {simview-6.1.0 → simview-6.1.1}/simview/__init__.py +0 -0
  16. {simview-6.1.0 → simview-6.1.1}/simview/__main__.py +0 -0
  17. {simview-6.1.0 → simview-6.1.1}/simview/columnar.py +0 -0
  18. {simview-6.1.0 → simview-6.1.1}/simview/diff.py +0 -0
  19. {simview-6.1.0 → simview-6.1.1}/simview/info.py +0 -0
  20. {simview-6.1.0 → simview-6.1.1}/simview/launcher.py +0 -0
  21. {simview-6.1.0 → simview-6.1.1}/simview/live.py +0 -0
  22. {simview-6.1.0 → simview-6.1.1}/simview/merge.py +0 -0
  23. {simview-6.1.0 → simview-6.1.1}/simview/model.py +0 -0
  24. {simview-6.1.0 → simview-6.1.1}/simview/py.typed +0 -0
  25. {simview-6.1.0 → simview-6.1.1}/simview/remote.py +0 -0
  26. {simview-6.1.0 → simview-6.1.1}/simview/render.py +0 -0
  27. {simview-6.1.0 → simview-6.1.1}/simview/scene.py +0 -0
  28. {simview-6.1.0 → simview-6.1.1}/simview/server.py +0 -0
  29. {simview-6.1.0 → simview-6.1.1}/simview/state.py +0 -0
  30. {simview-6.1.0 → simview-6.1.1}/simview/static/css/controls.css +0 -0
  31. {simview-6.1.0 → simview-6.1.1}/simview/static/js/components/BatchManager.js +0 -0
  32. {simview-6.1.0 → simview-6.1.1}/simview/static/js/components/InteractionController.js +0 -0
  33. {simview-6.1.0 → simview-6.1.1}/simview/static/js/components/Scene.js +0 -0
  34. {simview-6.1.0 → simview-6.1.1}/simview/static/js/components/StateStore.js +0 -0
  35. {simview-6.1.0 → simview-6.1.1}/simview/static/js/components/WindowedField.js +0 -0
  36. {simview-6.1.0 → simview-6.1.1}/simview/static/js/config.js +0 -0
  37. {simview-6.1.0 → simview-6.1.1}/simview/static/js/main.js +0 -0
  38. {simview-6.1.0 → simview-6.1.1}/simview/static/js/objects/Body.js +0 -0
  39. {simview-6.1.0 → simview-6.1.1}/simview/static/js/objects/StaticObject.js +0 -0
  40. {simview-6.1.0 → simview-6.1.1}/simview/static/js/objects/Terrain.js +0 -0
  41. {simview-6.1.0 → simview-6.1.1}/simview/static/js/objects/colormap.js +0 -0
  42. {simview-6.1.0 → simview-6.1.1}/simview/static/js/objects/similarity.js +0 -0
  43. {simview-6.1.0 → simview-6.1.1}/simview/static/js/objects/utils.js +0 -0
  44. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/AnalysisPanel.js +0 -0
  45. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/BatchLegend.js +0 -0
  46. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/BodyStateWindow.js +0 -0
  47. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/ErrorMetrics.js +0 -0
  48. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/Legend.js +0 -0
  49. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/PlaybackControls.js +0 -0
  50. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/TerrainProfile.js +0 -0
  51. {simview-6.1.0 → simview-6.1.1}/simview/static/js/ui/chartControls.js +0 -0
  52. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/batchPresets.js +0 -0
  53. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/batchVisibility.js +0 -0
  54. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/blobCodec.js +0 -0
  55. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/blobWindow.js +0 -0
  56. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/bodyTransforms.js +0 -0
  57. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/cameraRange.js +0 -0
  58. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/csv.js +0 -0
  59. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/episodes.js +0 -0
  60. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/errorMath.js +0 -0
  61. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/interpolate.js +0 -0
  62. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/keyboard.js +0 -0
  63. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/liveFollow.js +0 -0
  64. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/terrainSample.js +0 -0
  65. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/uplot.js +0 -0
  66. {simview-6.1.0 → simview-6.1.1}/simview/static/js/utils/viewerDefaults.js +0 -0
  67. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/js-colormaps.js +0 -0
  68. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +0 -0
  69. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +0 -0
  70. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/three-0.174.0/three.core.js +0 -0
  71. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/three-0.174.0/three.module.js +0 -0
  72. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/uPlot.esm.js +0 -0
  73. {simview-6.1.0 → simview-6.1.1}/simview/static/lib/uPlot.min.css +0 -0
  74. {simview-6.1.0 → simview-6.1.1}/simview/static/textures/contacts/red-cross0.png +0 -0
  75. {simview-6.1.0 → simview-6.1.1}/simview/static/textures/points/ball1.png +0 -0
  76. {simview-6.1.0 → simview-6.1.1}/simview/templates/index.html +0 -0
  77. {simview-6.1.0 → simview-6.1.1}/simview/terrain.py +0 -0
  78. {simview-6.1.0 → simview-6.1.1}/simview/utils.py +0 -0
  79. {simview-6.1.0 → simview-6.1.1}/simview.egg-info/SOURCES.txt +0 -0
  80. {simview-6.1.0 → simview-6.1.1}/simview.egg-info/dependency_links.txt +0 -0
  81. {simview-6.1.0 → simview-6.1.1}/simview.egg-info/entry_points.txt +0 -0
  82. {simview-6.1.0 → simview-6.1.1}/simview.egg-info/requires.txt +0 -0
  83. {simview-6.1.0 → simview-6.1.1}/simview.egg-info/top_level.txt +0 -0
  84. {simview-6.1.0 → simview-6.1.1}/tests/test_batch_selection.py +0 -0
  85. {simview-6.1.0 → simview-6.1.1}/tests/test_cli.py +0 -0
  86. {simview-6.1.0 → simview-6.1.1}/tests/test_columnar_ondisk.py +0 -0
  87. {simview-6.1.0 → simview-6.1.1}/tests/test_columnar_states.py +0 -0
  88. {simview-6.1.0 → simview-6.1.1}/tests/test_contacts.py +0 -0
  89. {simview-6.1.0 → simview-6.1.1}/tests/test_diff.py +0 -0
  90. {simview-6.1.0 → simview-6.1.1}/tests/test_embed_defaults.py +0 -0
  91. {simview-6.1.0 → simview-6.1.1}/tests/test_episodes.py +0 -0
  92. {simview-6.1.0 → simview-6.1.1}/tests/test_info.py +0 -0
  93. {simview-6.1.0 → simview-6.1.1}/tests/test_launcher.py +0 -0
  94. {simview-6.1.0 → simview-6.1.1}/tests/test_live.py +0 -0
  95. {simview-6.1.0 → simview-6.1.1}/tests/test_merge.py +0 -0
  96. {simview-6.1.0 → simview-6.1.1}/tests/test_pointcloud_features.py +0 -0
  97. {simview-6.1.0 → simview-6.1.1}/tests/test_remote.py +0 -0
  98. {simview-6.1.0 → simview-6.1.1}/tests/test_roundtrip.py +0 -0
  99. {simview-6.1.0 → simview-6.1.1}/tests/test_scene.py +0 -0
  100. {simview-6.1.0 → simview-6.1.1}/tests/test_server.py +0 -0
  101. {simview-6.1.0 → simview-6.1.1}/tests/test_show.py +0 -0
  102. {simview-6.1.0 → simview-6.1.1}/tests/test_terrain.py +0 -0
  103. {simview-6.1.0 → simview-6.1.1}/tests/test_terrain_query.py +0 -0
  104. {simview-6.1.0 → simview-6.1.1}/tests/test_trajectory.py +0 -0
  105. {simview-6.1.0 → simview-6.1.1}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simview
3
- Version: 6.1.0
3
+ Version: 6.1.1
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.0"
7
+ version = "6.1.1"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.12"
10
10
  license = "BSD-3-Clause"
@@ -602,6 +602,9 @@ export class SimView {
602
602
  // actually flips body/terrain visuals) stay in sync instead of
603
603
  // uiState silently drifting out from under the displayed panel.
604
604
  if (this.uiControls) {
605
+ if (Number.isFinite(state.playbackSpeed) && this.animationController) {
606
+ this.animationController.setSpeed(state.playbackSpeed);
607
+ }
605
608
  this.uiControls.applyViewState(state);
606
609
  }
607
610
  } catch (e) {
@@ -623,6 +626,10 @@ export class SimView {
623
626
  bodyVisualizationMode: this.uiState.bodyVisualizationMode,
624
627
  terrainColorMode: this.uiState.terrainColorMode,
625
628
  toggles: toggleMapFromUiState(this.uiState),
629
+ pointCloudsVisible: this.uiState.pointCloudsVisible,
630
+ trackBody: this.uiState.trackBody,
631
+ terrainColorMap: this.uiState.terrainColorMap,
632
+ playbackSpeed: this.animationController ? this.animationController.playbackSpeed : undefined,
626
633
  };
627
634
  }
628
635
 
@@ -126,6 +126,10 @@ export class AnimationController {
126
126
 
127
127
  setSpeed(speed) {
128
128
  this.playbackSpeed = speed;
129
+ // Keep the playback bar's dropdown in step with programmatic callers.
130
+ if (this.playbackControls && this.playbackControls.speedSelect) {
131
+ this.playbackControls.speedSelect.value = String(speed);
132
+ }
129
133
  }
130
134
 
131
135
  setRecordingFormat(format) {
@@ -607,6 +607,21 @@ export class UIControls {
607
607
  if (ctrl) ctrl.setValue(state.terrainColorMode);
608
608
  }
609
609
 
610
+ if (typeof state.terrainColorMap === "string") {
611
+ const known = Array.isArray(colorMapOptions) ? colorMapOptions : Object.keys(colorMapOptions);
612
+ const ctrl = this.findController("colorMap");
613
+ if (ctrl && known.includes(state.terrainColorMap)) ctrl.setValue(state.terrainColorMap);
614
+ }
615
+
616
+ if (typeof state.pointCloudsVisible === "boolean") {
617
+ const ctrl = this.findController("showPointClouds");
618
+ if (ctrl) ctrl.setValue(state.pointCloudsVisible);
619
+ }
620
+
621
+ if (typeof state.trackBody === "string" && this.trackBodyCtrl) {
622
+ if (this.trackableBodyNames().includes(state.trackBody)) this.trackBodyCtrl.setValue(state.trackBody);
623
+ }
624
+
610
625
  if (state.toggles && typeof state.toggles === "object") {
611
626
  const propertyForKey = {
612
627
  axesVisible: "showAxes",
@@ -354,6 +354,7 @@ export class ScalarPlotter {
354
354
  }
355
355
 
356
356
  setEndIndex(newEndIndex, force = false) {
357
+ if (this.times.length === 0) return; // store not loaded yet (initFromStore pending)
357
358
  if (newEndIndex < 0 || newEndIndex >= this.times.length) {
358
359
  console.warn(
359
360
  "Invalid end index. Must be within the range of time values."
@@ -30,11 +30,9 @@ const BOOLEAN_FLAG_KEYS = [
30
30
  "terrainVisualizationModes.normals",
31
31
  ];
32
32
 
33
- // Deliberately NOT in the list above: `pointCloudsVisible`. Appending only
34
- // works for flags that default off -- a link made before the flag existed has
35
- // no bit for it, which decodes as false, so a default-on flag would arrive
36
- // switched off and hide point clouds on every old link. Adding it needs a
37
- // format version that can tell "absent" from "false".
33
+ // Deliberately NOT in the list above: `pointCloudsVisible`. It defaults on,
34
+ // so a bit would decode old links (bit absent) as off; it travels as the
35
+ // named `pc=0|1` key instead, where absent means "leave alone".
38
36
 
39
37
  function getPath(obj, path) {
40
38
  return path.split(".").reduce((o, k) => (o && typeof o === "object" ? o[k] : undefined), obj);
@@ -87,6 +85,11 @@ function decodeFlags(mask) {
87
85
  // bodyVisualizationMode: string,
88
86
  // terrainColorMode: string,
89
87
  // toggles: { [key in BOOLEAN_FLAG_KEYS]?: boolean },
88
+ // pointCloudsVisible: boolean, // `pc=0|1` -- a named key, not a flag bit,
89
+ // // so "absent" (leave alone) != false
90
+ // trackBody: string, // `track=`
91
+ // terrainColorMap: string, // `cmap=`
92
+ // playbackSpeed: number, // `speed=`
90
93
  // }
91
94
  export function serializeViewState(state) {
92
95
  if (!state || typeof state !== "object") return "";
@@ -116,6 +119,18 @@ export function serializeViewState(state) {
116
119
  if (state.toggles && typeof state.toggles === "object") {
117
120
  params.push(`flags=${encodeFlags(state.toggles)}`);
118
121
  }
122
+ if (typeof state.pointCloudsVisible === "boolean") {
123
+ params.push(`pc=${state.pointCloudsVisible ? 1 : 0}`);
124
+ }
125
+ if (typeof state.trackBody === "string" && state.trackBody) {
126
+ params.push(`track=${encodeURIComponent(state.trackBody)}`);
127
+ }
128
+ if (typeof state.terrainColorMap === "string" && state.terrainColorMap) {
129
+ params.push(`cmap=${encodeURIComponent(state.terrainColorMap)}`);
130
+ }
131
+ if (Number.isFinite(state.playbackSpeed) && state.playbackSpeed > 0) {
132
+ params.push(`speed=${fmtNum(state.playbackSpeed)}`);
133
+ }
119
134
 
120
135
  return `#${params.join("&")}`;
121
136
  }
@@ -155,6 +170,15 @@ export function parseViewState(hash) {
155
170
  const mask = parseInt(params.get("flags"), 10);
156
171
  if (Number.isInteger(mask)) state.toggles = decodeFlags(mask);
157
172
 
173
+ const pc = params.get("pc");
174
+ if (pc === "0" || pc === "1") state.pointCloudsVisible = pc === "1";
175
+ const track = params.get("track");
176
+ if (track) state.trackBody = track;
177
+ const cmap = params.get("cmap");
178
+ if (cmap) state.terrainColorMap = cmap;
179
+ const speed = num("speed");
180
+ if (Number.isFinite(speed) && speed > 0) state.playbackSpeed = speed;
181
+
158
182
  return state;
159
183
  }
160
184
 
@@ -47,6 +47,10 @@ def view_hash(
47
47
  body_mode: str | None = None,
48
48
  terrain_color_mode: str | None = None,
49
49
  flags: Mapping[str, bool] | None = None,
50
+ point_clouds: bool | None = None,
51
+ track: str | None = None,
52
+ color_map: str | None = None,
53
+ speed: float | None = None,
50
54
  data: str | None = None,
51
55
  ui: bool | None = None,
52
56
  ) -> str:
@@ -55,6 +59,9 @@ def view_hash(
55
59
  `t` is the playback time in seconds, `cam`/`tgt` the camera position and
56
60
  orbit target, `batch` the focused batch index, `flags` a map of the dotted
57
61
  toggle names in `BOOLEAN_FLAG_KEYS` (unlisted ones default to off).
62
+ `point_clouds`, `track` (a body name, or ``"None"``), `color_map` and
63
+ `speed` are carried as named keys; leaving one ``None`` leaves the
64
+ viewer's current setting alone.
58
65
  `data` (base URL of a static bundle, see `SimulationScene.save_static`) and
59
66
  `ui=False` (hide all panels) are startup options, not view state.
60
67
  """
@@ -81,6 +88,16 @@ def view_hash(
81
88
  )
82
89
  mask = sum(1 << i for i, k in enumerate(BOOLEAN_FLAG_KEYS) if flags.get(k))
83
90
  params.append(f"flags={mask}")
91
+ if point_clouds is not None:
92
+ params.append(f"pc={int(bool(point_clouds))}")
93
+ if track:
94
+ params.append(f"track={quote(track, safe='')}")
95
+ if color_map:
96
+ params.append(f"cmap={quote(color_map, safe='')}")
97
+ if speed is not None:
98
+ if speed <= 0:
99
+ raise ValueError(f"speed must be positive; got {speed!r}")
100
+ params.append(f"speed={_num(speed)}")
84
101
  if params:
85
102
  params.insert(0, "v=1")
86
103
  if data is not None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simview
3
- Version: 6.1.0
3
+ Version: 6.1.1
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
@@ -35,6 +35,13 @@ def test_view_hash():
35
35
  assert view_hash(ui=False, data="http://h/x") == "#data=http%3A%2F%2Fh%2Fx&ui=0"
36
36
  with pytest.raises(ValueError):
37
37
  view_hash(flags={"nope": True})
38
+ # Named carry-over keys, in the JS serializer's order; absent means "leave alone".
39
+ assert (
40
+ view_hash(point_clouds=False, track="robot 1", color_map="viridis", speed=0.25)
41
+ == "#v=1&pc=0&track=robot%201&cmap=viridis&speed=0.25"
42
+ )
43
+ with pytest.raises(ValueError):
44
+ view_hash(speed=0)
38
45
 
39
46
 
40
47
  def _urls(o):
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