simview 4.0.0__tar.gz → 4.2.0__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 (209) hide show
  1. {simview-4.0.0/simview.egg-info → simview-4.2.0}/PKG-INFO +3 -1
  2. {simview-4.0.0 → simview-4.2.0}/README.md +2 -0
  3. {simview-4.0.0 → simview-4.2.0}/pyproject.toml +1 -1
  4. {simview-4.0.0 → simview-4.2.0}/simview/__init__.py +3 -0
  5. {simview-4.0.0 → simview-4.2.0}/simview/__main__.py +125 -43
  6. simview-4.2.0/simview/columnar.py +380 -0
  7. {simview-4.0.0 → simview-4.2.0}/simview/diff.py +218 -36
  8. {simview-4.0.0 → simview-4.2.0}/simview/info.py +31 -10
  9. simview-4.2.0/simview/live.py +354 -0
  10. simview-4.2.0/simview/merge.py +969 -0
  11. {simview-4.0.0 → simview-4.2.0}/simview/model.py +136 -5
  12. simview-4.2.0/simview/remote.py +359 -0
  13. {simview-4.0.0 → simview-4.2.0}/simview/scene.py +114 -10
  14. {simview-4.0.0 → simview-4.2.0}/simview/server.py +187 -246
  15. {simview-4.0.0 → simview-4.2.0}/simview/static/js/SimView.js +84 -1
  16. {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/AnimationController.js +3 -0
  17. {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/BatchManager.js +80 -4
  18. {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/InteractionController.js +4 -273
  19. simview-4.2.0/simview/static/js/components/InteractionControls.js +63 -0
  20. {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/StateStore.js +20 -3
  21. simview-4.2.0/simview/static/js/components/WindowedField.js +153 -0
  22. {simview-4.0.0 → simview-4.2.0}/simview/static/js/config.js +0 -16
  23. {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/Body.js +191 -64
  24. {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/StaticObject.js +22 -0
  25. {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/Terrain.js +48 -7
  26. {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/utils.js +10 -2
  27. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/Controls.js +27 -5
  28. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/ErrorMetrics.js +48 -20
  29. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/PlaybackControls.js +168 -1
  30. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/ScalarPlotter.js +113 -1
  31. simview-4.2.0/simview/static/js/utils/batchVisibility.js +46 -0
  32. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/blobCodec.js +3 -1
  33. simview-4.2.0/simview/static/js/utils/blobWindow.js +107 -0
  34. simview-4.2.0/simview/static/js/utils/episodes.js +120 -0
  35. {simview-4.0.0 → simview-4.2.0}/simview/terrain.py +5 -1
  36. {simview-4.0.0 → simview-4.2.0/simview.egg-info}/PKG-INFO +3 -1
  37. {simview-4.0.0 → simview-4.2.0}/simview.egg-info/SOURCES.txt +10 -0
  38. simview-4.2.0/tests/test_batch_selection.py +73 -0
  39. {simview-4.0.0 → simview-4.2.0}/tests/test_cli.py +256 -0
  40. simview-4.2.0/tests/test_columnar_ondisk.py +380 -0
  41. {simview-4.0.0 → simview-4.2.0}/tests/test_columnar_states.py +1 -1
  42. {simview-4.0.0 → simview-4.2.0}/tests/test_diff.py +115 -0
  43. simview-4.2.0/tests/test_episodes.py +171 -0
  44. {simview-4.0.0 → simview-4.2.0}/tests/test_live.py +136 -5
  45. simview-4.2.0/tests/test_merge.py +992 -0
  46. {simview-4.0.0 → simview-4.2.0}/tests/test_pointcloud_features.py +4 -2
  47. simview-4.2.0/tests/test_remote.py +375 -0
  48. {simview-4.0.0 → simview-4.2.0}/tests/test_roundtrip.py +75 -8
  49. {simview-4.0.0 → simview-4.2.0}/tests/test_scene.py +22 -0
  50. {simview-4.0.0 → simview-4.2.0}/tests/test_server.py +17 -0
  51. {simview-4.0.0 → simview-4.2.0}/tests/test_show.py +28 -0
  52. {simview-4.0.0 → simview-4.2.0}/tests/test_terrain.py +7 -3
  53. simview-4.0.0/simview/live.py +0 -216
  54. simview-4.0.0/simview/merge.py +0 -565
  55. simview-4.0.0/simview/static/js/components/InteractionControls.js +0 -116
  56. simview-4.0.0/tests/test_merge.py +0 -535
  57. {simview-4.0.0 → simview-4.2.0}/LICENSE +0 -0
  58. {simview-4.0.0 → simview-4.2.0}/MANIFEST.in +0 -0
  59. {simview-4.0.0 → simview-4.2.0}/setup.cfg +0 -0
  60. {simview-4.0.0 → simview-4.2.0}/simview/launcher.py +0 -0
  61. {simview-4.0.0 → simview-4.2.0}/simview/py.typed +0 -0
  62. {simview-4.0.0 → simview-4.2.0}/simview/render.py +0 -0
  63. {simview-4.0.0 → simview-4.2.0}/simview/state.py +0 -0
  64. {simview-4.0.0 → simview-4.2.0}/simview/static/css/controls.css +0 -0
  65. {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/Scene.js +0 -0
  66. {simview-4.0.0 → simview-4.2.0}/simview/static/js/main.js +0 -0
  67. {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/colormap.js +0 -0
  68. {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/similarity.js +0 -0
  69. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/AnalysisPanel.js +0 -0
  70. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/BatchLegend.js +0 -0
  71. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/BodyStateWindow.js +0 -0
  72. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/Legend.js +0 -0
  73. {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/TerrainProfile.js +0 -0
  74. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/batchPresets.js +0 -0
  75. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/bodyTransforms.js +0 -0
  76. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/csv.js +0 -0
  77. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/errorMath.js +0 -0
  78. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/injectStyles.js +0 -0
  79. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/interpolate.js +0 -0
  80. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/liveFollow.js +0 -0
  81. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/loadRecordingLibs.js +0 -0
  82. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/terrainSample.js +0 -0
  83. {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/viewState.js +0 -0
  84. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/index.min.js +0 -0
  85. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/Color.js +0 -0
  86. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/chroma.js +0 -0
  87. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/colors/colorbrewer.js +0 -0
  88. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/colors/w3cx11.js +0 -0
  89. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/average.js +0 -0
  90. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/bezier.js +0 -0
  91. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/blend.js +0 -0
  92. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/cubehelix.js +0 -0
  93. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/mix.js +0 -0
  94. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/random.js +0 -0
  95. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/scale.js +0 -0
  96. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/_hsx.js +0 -0
  97. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hcg.js +0 -0
  98. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsi.js +0 -0
  99. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsl.js +0 -0
  100. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsv.js +0 -0
  101. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/index.js +0 -0
  102. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lab.js +0 -0
  103. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lch.js +0 -0
  104. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lrgb.js +0 -0
  105. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/num.js +0 -0
  106. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/oklab.js +0 -0
  107. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/oklch.js +0 -0
  108. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/rgb.js +0 -0
  109. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/cmyk2rgb.js +0 -0
  110. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/index.js +0 -0
  111. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/rgb2cmyk.js +0 -0
  112. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/css2rgb.js +0 -0
  113. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/hsl2css.js +0 -0
  114. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/index.js +0 -0
  115. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/lab2css.js +0 -0
  116. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/lch2css.js +0 -0
  117. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/oklab2css.js +0 -0
  118. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/oklch2css.js +0 -0
  119. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/rgb2css.js +0 -0
  120. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/gl/index.js +0 -0
  121. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/hcg2rgb.js +0 -0
  122. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/index.js +0 -0
  123. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/rgb2hcg.js +0 -0
  124. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hex/hex2rgb.js +0 -0
  125. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hex/index.js +0 -0
  126. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hex/rgb2hex.js +0 -0
  127. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/hsi2rgb.js +0 -0
  128. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/index.js +0 -0
  129. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/rgb2hsi.js +0 -0
  130. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/hsl2rgb.js +0 -0
  131. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/index.js +0 -0
  132. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/rgb2hsl.js +0 -0
  133. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/hsv2rgb.js +0 -0
  134. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/index.js +0 -0
  135. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/rgb2hsv.js +0 -0
  136. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/input.js +0 -0
  137. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/index.js +0 -0
  138. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/lab-constants.js +0 -0
  139. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/lab2rgb.js +0 -0
  140. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/rgb2lab.js +0 -0
  141. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/hcl2rgb.js +0 -0
  142. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/index.js +0 -0
  143. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lab2lch.js +0 -0
  144. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2lab.js +0 -0
  145. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2rgb.js +0 -0
  146. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/rgb2lch.js +0 -0
  147. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/named/index.js +0 -0
  148. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/num/index.js +0 -0
  149. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/num/num2rgb.js +0 -0
  150. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/num/rgb2num.js +0 -0
  151. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/index.js +0 -0
  152. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/oklab2rgb.js +0 -0
  153. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/rgb2oklab.js +0 -0
  154. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/index.js +0 -0
  155. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/oklch2rgb.js +0 -0
  156. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/rgb2oklch.js +0 -0
  157. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/rgb/index.js +0 -0
  158. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/temp/index.js +0 -0
  159. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/temp/rgb2temperature.js +0 -0
  160. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/temp/temperature2rgb.js +0 -0
  161. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/alpha.js +0 -0
  162. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/clipped.js +0 -0
  163. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/darken.js +0 -0
  164. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/get.js +0 -0
  165. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/luminance.js +0 -0
  166. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/mix.js +0 -0
  167. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/premultiply.js +0 -0
  168. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/saturate.js +0 -0
  169. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/set.js +0 -0
  170. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/shade.js +0 -0
  171. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/analyze.js +0 -0
  172. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/clip_rgb.js +0 -0
  173. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/contrast.js +0 -0
  174. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/contrastAPCA.js +0 -0
  175. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/delta-e.js +0 -0
  176. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/distance.js +0 -0
  177. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/index.js +0 -0
  178. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/last.js +0 -0
  179. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/limit.js +0 -0
  180. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/multiply-matrices.js +0 -0
  181. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/scales.js +0 -0
  182. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/type.js +0 -0
  183. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/unpack.js +0 -0
  184. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/valid.js +0 -0
  185. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/version.js +0 -0
  186. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/download.js +0 -0
  187. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/js-colormaps.js +0 -0
  188. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/tar.js +0 -0
  189. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +0 -0
  190. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +0 -0
  191. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/three.core.js +0 -0
  192. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/three.module.js +0 -0
  193. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/uPlot.esm.js +0 -0
  194. {simview-4.0.0 → simview-4.2.0}/simview/static/lib/uPlot.min.css +0 -0
  195. {simview-4.0.0 → simview-4.2.0}/simview/static/textures/contacts/red-cross0.png +0 -0
  196. {simview-4.0.0 → simview-4.2.0}/simview/static/textures/points/ball0.png +0 -0
  197. {simview-4.0.0 → simview-4.2.0}/simview/static/textures/points/ball1.png +0 -0
  198. {simview-4.0.0 → simview-4.2.0}/simview/templates/index.html +0 -0
  199. {simview-4.0.0 → simview-4.2.0}/simview/utils.py +0 -0
  200. {simview-4.0.0 → simview-4.2.0}/simview.egg-info/dependency_links.txt +0 -0
  201. {simview-4.0.0 → simview-4.2.0}/simview.egg-info/entry_points.txt +0 -0
  202. {simview-4.0.0 → simview-4.2.0}/simview.egg-info/requires.txt +0 -0
  203. {simview-4.0.0 → simview-4.2.0}/simview.egg-info/top_level.txt +0 -0
  204. {simview-4.0.0 → simview-4.2.0}/tests/test_contacts.py +0 -0
  205. {simview-4.0.0 → simview-4.2.0}/tests/test_info.py +0 -0
  206. {simview-4.0.0 → simview-4.2.0}/tests/test_launcher.py +0 -0
  207. {simview-4.0.0 → simview-4.2.0}/tests/test_terrain_query.py +0 -0
  208. {simview-4.0.0 → simview-4.2.0}/tests/test_trajectory.py +0 -0
  209. {simview-4.0.0 → simview-4.2.0}/tests/test_utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: simview
3
- Version: 4.0.0
3
+ Version: 4.2.0
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
@@ -62,6 +62,8 @@ Want to try it without installing anything? There's a
62
62
  - **Interactive UI**: Web-based controls for playback, camera, and data inspection.
63
63
  - **Python API**: Easy-to-use API for generating scenes and launching the visualizer directly from your code.
64
64
  - **JSON Support**: Load and save simulation data using a portable JSON format.
65
+ - **Remote Files**: Open a scene straight off a compute host with `simview host:path/to/scene.json` — fetched over SSH, compressed on the wire, and cached locally.
66
+ - **Comparing Runs**: Merge several scene files into one, taking whole files or just picked batches — `simview gt.json method_a.json#1 method_b.json#1`.
65
67
 
66
68
  ---
67
69
 
@@ -29,6 +29,8 @@ Want to try it without installing anything? There's a
29
29
  - **Interactive UI**: Web-based controls for playback, camera, and data inspection.
30
30
  - **Python API**: Easy-to-use API for generating scenes and launching the visualizer directly from your code.
31
31
  - **JSON Support**: Load and save simulation data using a portable JSON format.
32
+ - **Remote Files**: Open a scene straight off a compute host with `simview host:path/to/scene.json` — fetched over SSH, compressed on the wire, and cached locally.
33
+ - **Comparing Runs**: Merge several scene files into one, taking whole files or just picked batches — `simview gt.json method_a.json#1 method_b.json#1`.
32
34
 
33
35
  ---
34
36
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "simview"
7
- version = "4.0.0"
7
+ version = "4.2.0"
8
8
  readme = "README.md"
9
9
  requires-python = ">=3.12"
10
10
  license = "BSD-3-Clause"
@@ -29,6 +29,7 @@ _LAZY_EXPORTS = {
29
29
  "SimViewStaticObject": "simview.model",
30
30
  "SimViewTerrain": "simview.model",
31
31
  "SimViewModel": "simview.model",
32
+ "SimViewEpisode": "simview.model",
32
33
  "BodyShapeType": "simview.model",
33
34
  "OptionalBodyStateAttribute": "simview.model",
34
35
  "SimViewBodyState": "simview.state",
@@ -42,6 +43,7 @@ if TYPE_CHECKING:
42
43
  BodyShapeType,
43
44
  OptionalBodyStateAttribute,
44
45
  SimViewBody,
46
+ SimViewEpisode,
45
47
  SimViewModel,
46
48
  SimViewStaticObject,
47
49
  SimViewTerrain,
@@ -58,6 +60,7 @@ __all__ = [
58
60
  "SimViewStaticObject",
59
61
  "SimViewTerrain",
60
62
  "SimViewModel",
63
+ "SimViewEpisode",
61
64
  "BodyShapeType",
62
65
  "OptionalBodyStateAttribute",
63
66
  "SimViewBodyState",
@@ -7,7 +7,7 @@ import sys
7
7
  import tempfile
8
8
  from pathlib import Path
9
9
 
10
- from simview import CACHE_DIR, __version__
10
+ from simview import CACHE_DIR, __version__, remote
11
11
  from simview.server import SimViewServer
12
12
 
13
13
  logger = logging.getLogger("simview.cli")
@@ -43,12 +43,33 @@ def _package_version() -> str:
43
43
  return __version__
44
44
 
45
45
 
46
+ def _dir_size(path: Path) -> int:
47
+ total = 0
48
+ for entry in path.rglob("*"):
49
+ try:
50
+ if entry.is_file():
51
+ total += entry.stat().st_size
52
+ except OSError:
53
+ pass
54
+ return total
55
+
56
+
46
57
  def clear_cache():
47
- # Legacy cache directories (kept for cleanup of older installs).
48
- for cache_dir in (Path("/tmp") / CACHE_DIR, Path.home() / ".cache" / CACHE_DIR):
49
- if cache_dir.exists():
50
- logger.info("Removing %s", cache_dir)
51
- shutil.rmtree(cache_dir, ignore_errors=True)
58
+ """Remove simview's on-disk cache: scene files fetched from remote hosts
59
+ (see `simview.remote`), plus locations left behind by older installs."""
60
+ freed = 0
61
+ seen: set[Path] = set()
62
+ for cache_dir in (
63
+ remote.cache_dir(),
64
+ Path("/tmp") / CACHE_DIR,
65
+ Path.home() / ".cache" / CACHE_DIR,
66
+ ):
67
+ if cache_dir in seen or not cache_dir.is_dir():
68
+ continue
69
+ seen.add(cache_dir)
70
+ freed += _dir_size(cache_dir)
71
+ logger.info("Removing %s", cache_dir)
72
+ shutil.rmtree(cache_dir, ignore_errors=True)
52
73
 
53
74
  # Temp scenes written by SimViewLauncher (tempfile.mkstemp with this prefix);
54
75
  # these leak if a launched viewer is killed before cleanup runs.
@@ -61,6 +82,8 @@ def clear_cache():
61
82
  logger.warning("Could not remove %s: %s", leftover, e)
62
83
  if removed:
63
84
  logger.info("Removed %d leftover temporary scene file(s).", removed)
85
+ if freed:
86
+ logger.info("Freed %s.", remote.human_bytes(freed))
64
87
 
65
88
  logger.info("Cache cleared.")
66
89
 
@@ -277,16 +300,22 @@ def run_render(path: Path, args: argparse.Namespace) -> None:
277
300
  sys.exit(1)
278
301
 
279
302
 
280
- def save_merged(paths: list[Path], out_path: Path) -> None:
281
- """Merge `paths` (must be >= 2) and write the result to `out_path`, gzipped
282
- if it ends in .gz, without starting the server."""
283
- if len(paths) < 2:
303
+ def save_merged(
304
+ paths: list[Path],
305
+ out_path: Path,
306
+ selections: list[str | None] | None = None,
307
+ ) -> None:
308
+ """Merge `paths` (must be >= 2, or 1 with a batch selection) and write the
309
+ result to `out_path`, gzipped if it ends in .gz, without starting the
310
+ server."""
311
+ selected = selections is not None and any(s is not None for s in selections)
312
+ if len(paths) < 2 and not selected:
284
313
  logger.error("Error: --save-merged requires at least 2 input files to merge.")
285
314
  sys.exit(1)
286
315
 
287
316
  from simview.merge import merge_simulation_files
288
317
 
289
- merged = merge_simulation_files(paths)
318
+ merged = merge_simulation_files(paths, selections)
290
319
  payload = json.dumps(merged).encode("utf-8")
291
320
  if out_path.suffix == ".gz":
292
321
  payload = gzip.compress(payload, compresslevel=1)
@@ -294,6 +323,21 @@ def save_merged(paths: list[Path], out_path: Path) -> None:
294
323
  logger.info("Merged scene written to %s", out_path)
295
324
 
296
325
 
326
+ def _resolve_input(spec: str, args: argparse.Namespace) -> Path:
327
+ """Resolve one CLI input to a local file, first fetching it over SSH if it
328
+ is an scp-style 'host:path' spec (see `simview.remote`). Everything
329
+ downstream only ever sees an ordinary local path."""
330
+ try:
331
+ path = remote.resolve_input(spec, refresh=args.refresh, offline=args.offline)
332
+ except remote.RemoteError as e:
333
+ logger.error("Error: %s", e)
334
+ sys.exit(1)
335
+ if not (path.exists() and path.is_file()):
336
+ logger.error("Error: File '%s' not found or is not a file.", path)
337
+ sys.exit(1)
338
+ return path
339
+
340
+
297
341
  def build_parser() -> argparse.ArgumentParser:
298
342
  parser = argparse.ArgumentParser(description="SimView CLI")
299
343
  parser.add_argument(
@@ -308,7 +352,14 @@ def build_parser() -> argparse.ArgumentParser:
308
352
  "a PNG screenshot (needs the 'render' extra). Multiple "
309
353
  "visualize-mode files are merged into one scene, each file's "
310
354
  "batches appended as extra batches (e.g. a real-world recording "
311
- "plus a simulated rerun)."
355
+ "plus a simulated rerun). Append '#<batches>' to a file to merge "
356
+ "only some of its batches (e.g. 'run.json#1', 'run.json#0,2-3', "
357
+ "'run.json#-1' or 'run.json#<batch name>'), so a ground truth "
358
+ "shared by several files isn't merged once per file. Any input "
359
+ "may instead be an scp-style "
360
+ "'host:path' spec (e.g. 'rci:~/results/scene.json'), which is "
361
+ "fetched over ssh -- compressed on the wire -- into a local cache "
362
+ "and re-fetched only when the remote file changes."
312
363
  ),
313
364
  )
314
365
  parser.add_argument(
@@ -420,7 +471,9 @@ def build_parser() -> argparse.ArgumentParser:
420
471
  "With 'simview diff <file>', restrict the trajectory diff to one "
421
472
  "body (matched by its full label, e.g. 'wheel_fl+wheel_fr', or by "
422
473
  "any single name inside a rigidly-grouped body). Default: diff "
423
- "every body present in states."
474
+ "every body present in states, plus any rigidly-attached body "
475
+ "resolvable from them. Poses are compared in world space (parent "
476
+ "chains resolved), matching the viewer's Error Metrics panel."
424
477
  ),
425
478
  )
426
479
  parser.add_argument(
@@ -488,6 +541,22 @@ def build_parser() -> argparse.ArgumentParser:
488
541
  "the next free port is used instead."
489
542
  ),
490
543
  )
544
+ parser.add_argument(
545
+ "--refresh",
546
+ action="store_true",
547
+ help=(
548
+ "Re-fetch remote 'host:path' inputs even if the cached copy still "
549
+ "matches the remote file."
550
+ ),
551
+ )
552
+ parser.add_argument(
553
+ "--offline",
554
+ action="store_true",
555
+ help=(
556
+ "Use the cached copy of remote 'host:path' inputs without contacting "
557
+ "the host at all; fails if nothing is cached for them yet."
558
+ ),
559
+ )
491
560
  parser.add_argument(
492
561
  "--no-browser",
493
562
  action="store_true",
@@ -551,6 +620,18 @@ def main():
551
620
  parser.print_help()
552
621
  sys.exit(1)
553
622
 
623
+ # Remote specs are an input-side convenience only; writing back over ssh is
624
+ # deliberately out of scope, so catch it here rather than at open() time.
625
+ for flag, value in (("--output", args.output), ("--save-merged", args.save_merged)):
626
+ if value is not None and remote.is_remote_spec(value):
627
+ logger.error(
628
+ "Error: %s must be a local path, but '%s' looks like a remote "
629
+ "'host:path' spec; remote specs are only supported for inputs.",
630
+ flag,
631
+ value,
632
+ )
633
+ sys.exit(1)
634
+
554
635
  if args.inputs and args.inputs[0] == "info":
555
636
  info_args = args.inputs[1:]
556
637
  if len(info_args) != 1:
@@ -559,10 +640,7 @@ def main():
559
640
  "'simview info scene.json'."
560
641
  )
561
642
  sys.exit(1)
562
- info_path = Path(info_args[0])
563
- if not (info_path.exists() and info_path.is_file()):
564
- logger.error("Error: File '%s' not found or is not a file.", info_path)
565
- sys.exit(1)
643
+ info_path = _resolve_input(info_args[0], args)
566
644
  run_info(info_path, as_json=args.json)
567
645
  return
568
646
 
@@ -574,10 +652,7 @@ def main():
574
652
  "e.g. 'simview terrain scene.json --point 0 0'."
575
653
  )
576
654
  sys.exit(1)
577
- terrain_path = Path(terrain_args[0])
578
- if not (terrain_path.exists() and terrain_path.is_file()):
579
- logger.error("Error: File '%s' not found or is not a file.", terrain_path)
580
- sys.exit(1)
655
+ terrain_path = _resolve_input(terrain_args[0], args)
581
656
  run_terrain(terrain_path, args)
582
657
  return
583
658
 
@@ -589,10 +664,7 @@ def main():
589
664
  "e.g. 'simview diff scene.json --batches 0 1'."
590
665
  )
591
666
  sys.exit(1)
592
- diff_path = Path(diff_args[0])
593
- if not (diff_path.exists() and diff_path.is_file()):
594
- logger.error("Error: File '%s' not found or is not a file.", diff_path)
595
- sys.exit(1)
667
+ diff_path = _resolve_input(diff_args[0], args)
596
668
  run_diff(diff_path, args)
597
669
  return
598
670
 
@@ -604,10 +676,7 @@ def main():
604
676
  "e.g. 'simview render scene.json --output frame.png'."
605
677
  )
606
678
  sys.exit(1)
607
- render_path = Path(render_args[0])
608
- if not (render_path.exists() and render_path.is_file()):
609
- logger.error("Error: File '%s' not found or is not a file.", render_path)
610
- sys.exit(1)
679
+ render_path = _resolve_input(render_args[0], args)
611
680
  run_render(render_path, args)
612
681
  return
613
682
 
@@ -615,22 +684,35 @@ def main():
615
684
  clear_cache()
616
685
  return
617
686
 
618
- paths = [Path(p) for p in args.inputs]
619
- for path in paths:
620
- if not (path.exists() and path.is_file()):
621
- logger.error("Error: File '%s' not found or is not a file.", path)
622
- sys.exit(1)
687
+ # Split "scene.json#1,3" into the file and the batches to take from it
688
+ # before resolving the file, so a remote spec can carry a selection too.
689
+ from simview.merge import split_batch_spec
623
690
 
624
- if args.save_merged:
625
- save_merged(paths, Path(args.save_merged))
626
- return
691
+ try:
692
+ split_inputs = [split_batch_spec(spec) for spec in args.inputs]
693
+ except ValueError as e:
694
+ logger.error("Error: %s", e)
695
+ sys.exit(1)
696
+ paths = [_resolve_input(spec, args) for spec, _ in split_inputs]
697
+ selections: list[str | None] = [selector for _, selector in split_inputs]
627
698
 
628
- SimViewServer.start(
629
- sim_path=paths if len(paths) > 1 else paths[0],
630
- host=args.host,
631
- preferred_port=args.port,
632
- open_browser=not args.no_browser,
633
- )
699
+ try:
700
+ if args.save_merged:
701
+ save_merged(paths, Path(args.save_merged), selections)
702
+ return
703
+
704
+ SimViewServer.start(
705
+ sim_path=paths if len(paths) > 1 else paths[0],
706
+ host=args.host,
707
+ preferred_port=args.port,
708
+ open_browser=not args.no_browser,
709
+ batch_selections=selections,
710
+ )
711
+ except ValueError as e:
712
+ # A bad batch selection ("scene.json#9" on a 2-batch file) is user
713
+ # error, not a crash: report it like any other bad argument.
714
+ logger.error("Error: %s", e)
715
+ sys.exit(1)
634
716
 
635
717
 
636
718
  if __name__ == "__main__":