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.
- {simview-4.0.0/simview.egg-info → simview-4.2.0}/PKG-INFO +3 -1
- {simview-4.0.0 → simview-4.2.0}/README.md +2 -0
- {simview-4.0.0 → simview-4.2.0}/pyproject.toml +1 -1
- {simview-4.0.0 → simview-4.2.0}/simview/__init__.py +3 -0
- {simview-4.0.0 → simview-4.2.0}/simview/__main__.py +125 -43
- simview-4.2.0/simview/columnar.py +380 -0
- {simview-4.0.0 → simview-4.2.0}/simview/diff.py +218 -36
- {simview-4.0.0 → simview-4.2.0}/simview/info.py +31 -10
- simview-4.2.0/simview/live.py +354 -0
- simview-4.2.0/simview/merge.py +969 -0
- {simview-4.0.0 → simview-4.2.0}/simview/model.py +136 -5
- simview-4.2.0/simview/remote.py +359 -0
- {simview-4.0.0 → simview-4.2.0}/simview/scene.py +114 -10
- {simview-4.0.0 → simview-4.2.0}/simview/server.py +187 -246
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/SimView.js +84 -1
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/AnimationController.js +3 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/BatchManager.js +80 -4
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/InteractionController.js +4 -273
- simview-4.2.0/simview/static/js/components/InteractionControls.js +63 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/StateStore.js +20 -3
- simview-4.2.0/simview/static/js/components/WindowedField.js +153 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/config.js +0 -16
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/Body.js +191 -64
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/StaticObject.js +22 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/Terrain.js +48 -7
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/utils.js +10 -2
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/Controls.js +27 -5
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/ErrorMetrics.js +48 -20
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/PlaybackControls.js +168 -1
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/ScalarPlotter.js +113 -1
- simview-4.2.0/simview/static/js/utils/batchVisibility.js +46 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/blobCodec.js +3 -1
- simview-4.2.0/simview/static/js/utils/blobWindow.js +107 -0
- simview-4.2.0/simview/static/js/utils/episodes.js +120 -0
- {simview-4.0.0 → simview-4.2.0}/simview/terrain.py +5 -1
- {simview-4.0.0 → simview-4.2.0/simview.egg-info}/PKG-INFO +3 -1
- {simview-4.0.0 → simview-4.2.0}/simview.egg-info/SOURCES.txt +10 -0
- simview-4.2.0/tests/test_batch_selection.py +73 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_cli.py +256 -0
- simview-4.2.0/tests/test_columnar_ondisk.py +380 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_columnar_states.py +1 -1
- {simview-4.0.0 → simview-4.2.0}/tests/test_diff.py +115 -0
- simview-4.2.0/tests/test_episodes.py +171 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_live.py +136 -5
- simview-4.2.0/tests/test_merge.py +992 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_pointcloud_features.py +4 -2
- simview-4.2.0/tests/test_remote.py +375 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_roundtrip.py +75 -8
- {simview-4.0.0 → simview-4.2.0}/tests/test_scene.py +22 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_server.py +17 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_show.py +28 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_terrain.py +7 -3
- simview-4.0.0/simview/live.py +0 -216
- simview-4.0.0/simview/merge.py +0 -565
- simview-4.0.0/simview/static/js/components/InteractionControls.js +0 -116
- simview-4.0.0/tests/test_merge.py +0 -535
- {simview-4.0.0 → simview-4.2.0}/LICENSE +0 -0
- {simview-4.0.0 → simview-4.2.0}/MANIFEST.in +0 -0
- {simview-4.0.0 → simview-4.2.0}/setup.cfg +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/launcher.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/py.typed +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/render.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/state.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/css/controls.css +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/components/Scene.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/main.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/colormap.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/objects/similarity.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/AnalysisPanel.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/BatchLegend.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/BodyStateWindow.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/Legend.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/ui/TerrainProfile.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/batchPresets.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/bodyTransforms.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/csv.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/errorMath.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/injectStyles.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/interpolate.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/liveFollow.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/loadRecordingLibs.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/terrainSample.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/js/utils/viewState.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/index.min.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/Color.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/chroma.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/colors/colorbrewer.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/colors/w3cx11.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/average.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/bezier.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/blend.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/cubehelix.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/mix.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/random.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/generator/scale.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/_hsx.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hcg.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsi.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsl.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/hsv.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lab.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lch.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/lrgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/num.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/oklab.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/oklch.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/interpolator/rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/cmyk2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/cmyk/rgb2cmyk.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/css2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/hsl2css.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/lab2css.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/lch2css.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/oklab2css.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/oklch2css.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/css/rgb2css.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/gl/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/hcg2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hcg/rgb2hcg.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hex/hex2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hex/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hex/rgb2hex.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/hsi2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsi/rgb2hsi.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/hsl2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsl/rgb2hsl.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/hsv2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/hsv/rgb2hsv.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/input.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/lab-constants.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/lab2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lab/rgb2lab.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/hcl2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lab2lch.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2lab.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/lch2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/lch/rgb2lch.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/named/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/num/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/num/num2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/num/rgb2num.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/oklab2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklab/rgb2oklab.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/oklch2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/oklch/rgb2oklch.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/rgb/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/temp/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/temp/rgb2temperature.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/io/temp/temperature2rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/alpha.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/clipped.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/darken.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/get.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/luminance.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/mix.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/premultiply.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/saturate.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/set.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/ops/shade.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/analyze.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/clip_rgb.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/contrast.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/contrastAPCA.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/delta-e.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/distance.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/index.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/last.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/limit.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/multiply-matrices.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/scales.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/type.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/unpack.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/utils/valid.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/chroma-js-3.1.2/src/version.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/download.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/js-colormaps.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/tar.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/addons/controls/OrbitControls.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/addons/libs/lil-gui.module.min.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/three.core.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/three-0.174.0/three.module.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/uPlot.esm.js +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/lib/uPlot.min.css +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/textures/contacts/red-cross0.png +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/textures/points/ball0.png +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/static/textures/points/ball1.png +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/templates/index.html +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview/utils.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview.egg-info/dependency_links.txt +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview.egg-info/entry_points.txt +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview.egg-info/requires.txt +0 -0
- {simview-4.0.0 → simview-4.2.0}/simview.egg-info/top_level.txt +0 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_contacts.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_info.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_launcher.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_terrain_query.py +0 -0
- {simview-4.0.0 → simview-4.2.0}/tests/test_trajectory.py +0 -0
- {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.
|
|
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
|
|
|
@@ -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
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
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(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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 =
|
|
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
|
-
|
|
619
|
-
|
|
620
|
-
|
|
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
|
-
|
|
625
|
-
|
|
626
|
-
|
|
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
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
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__":
|