vispy 0.15.0__cp313-cp313-macosx_11_0_arm64.whl
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.
Potentially problematic release.
This version of vispy might be problematic. Click here for more details.
- vispy/__init__.py +33 -0
- vispy/app/__init__.py +15 -0
- vispy/app/_default_app.py +76 -0
- vispy/app/_detect_eventloop.py +148 -0
- vispy/app/application.py +263 -0
- vispy/app/backends/__init__.py +52 -0
- vispy/app/backends/_egl.py +264 -0
- vispy/app/backends/_glfw.py +513 -0
- vispy/app/backends/_jupyter_rfb.py +278 -0
- vispy/app/backends/_offscreen_util.py +121 -0
- vispy/app/backends/_osmesa.py +235 -0
- vispy/app/backends/_pyglet.py +451 -0
- vispy/app/backends/_pyqt4.py +36 -0
- vispy/app/backends/_pyqt5.py +36 -0
- vispy/app/backends/_pyqt6.py +40 -0
- vispy/app/backends/_pyside.py +37 -0
- vispy/app/backends/_pyside2.py +52 -0
- vispy/app/backends/_pyside6.py +53 -0
- vispy/app/backends/_qt.py +1003 -0
- vispy/app/backends/_sdl2.py +444 -0
- vispy/app/backends/_template.py +244 -0
- vispy/app/backends/_test.py +8 -0
- vispy/app/backends/_tk.py +800 -0
- vispy/app/backends/_wx.py +476 -0
- vispy/app/backends/tests/__init__.py +0 -0
- vispy/app/backends/tests/test_offscreen_util.py +52 -0
- vispy/app/backends/tests/test_rfb.py +77 -0
- vispy/app/base.py +294 -0
- vispy/app/canvas.py +828 -0
- vispy/app/qt.py +92 -0
- vispy/app/tests/__init__.py +0 -0
- vispy/app/tests/qt-designer.ui +58 -0
- vispy/app/tests/test_app.py +442 -0
- vispy/app/tests/test_backends.py +164 -0
- vispy/app/tests/test_canvas.py +122 -0
- vispy/app/tests/test_context.py +92 -0
- vispy/app/tests/test_qt.py +47 -0
- vispy/app/tests/test_simultaneous.py +134 -0
- vispy/app/timer.py +174 -0
- vispy/color/__init__.py +17 -0
- vispy/color/_color_dict.py +193 -0
- vispy/color/color_array.py +447 -0
- vispy/color/color_space.py +181 -0
- vispy/color/colormap.py +1213 -0
- vispy/color/tests/__init__.py +0 -0
- vispy/color/tests/test_color.py +378 -0
- vispy/conftest.py +12 -0
- vispy/ext/__init__.py +0 -0
- vispy/ext/cocoapy.py +1522 -0
- vispy/ext/cubehelix.py +138 -0
- vispy/ext/egl.py +375 -0
- vispy/ext/fontconfig.py +118 -0
- vispy/ext/gdi32plus.py +206 -0
- vispy/ext/osmesa.py +105 -0
- vispy/geometry/__init__.py +23 -0
- vispy/geometry/_triangulation_debugger.py +171 -0
- vispy/geometry/calculations.py +162 -0
- vispy/geometry/curves.py +399 -0
- vispy/geometry/generation.py +643 -0
- vispy/geometry/isocurve.py +175 -0
- vispy/geometry/isosurface.py +465 -0
- vispy/geometry/meshdata.py +700 -0
- vispy/geometry/normals.py +78 -0
- vispy/geometry/parametric.py +56 -0
- vispy/geometry/polygon.py +137 -0
- vispy/geometry/rect.py +210 -0
- vispy/geometry/tests/__init__.py +0 -0
- vispy/geometry/tests/test_calculations.py +23 -0
- vispy/geometry/tests/test_generation.py +56 -0
- vispy/geometry/tests/test_meshdata.py +106 -0
- vispy/geometry/tests/test_triangulation.py +594 -0
- vispy/geometry/torusknot.py +142 -0
- vispy/geometry/triangulation.py +876 -0
- vispy/gloo/__init__.py +56 -0
- vispy/gloo/buffer.py +505 -0
- vispy/gloo/context.py +272 -0
- vispy/gloo/framebuffer.py +257 -0
- vispy/gloo/gl/__init__.py +234 -0
- vispy/gloo/gl/_constants.py +332 -0
- vispy/gloo/gl/_es2.py +986 -0
- vispy/gloo/gl/_gl2.py +1365 -0
- vispy/gloo/gl/_proxy.py +499 -0
- vispy/gloo/gl/_pyopengl2.py +362 -0
- vispy/gloo/gl/dummy.py +24 -0
- vispy/gloo/gl/es2.py +62 -0
- vispy/gloo/gl/gl2.py +98 -0
- vispy/gloo/gl/glplus.py +168 -0
- vispy/gloo/gl/pyopengl2.py +97 -0
- vispy/gloo/gl/tests/__init__.py +0 -0
- vispy/gloo/gl/tests/test_basics.py +282 -0
- vispy/gloo/gl/tests/test_functionality.py +568 -0
- vispy/gloo/gl/tests/test_names.py +246 -0
- vispy/gloo/gl/tests/test_use.py +71 -0
- vispy/gloo/glir.py +1824 -0
- vispy/gloo/globject.py +101 -0
- vispy/gloo/preprocessor.py +67 -0
- vispy/gloo/program.py +543 -0
- vispy/gloo/tests/__init__.py +0 -0
- vispy/gloo/tests/test_buffer.py +558 -0
- vispy/gloo/tests/test_context.py +119 -0
- vispy/gloo/tests/test_framebuffer.py +195 -0
- vispy/gloo/tests/test_glir.py +307 -0
- vispy/gloo/tests/test_globject.py +35 -0
- vispy/gloo/tests/test_program.py +302 -0
- vispy/gloo/tests/test_texture.py +732 -0
- vispy/gloo/tests/test_use_gloo.py +187 -0
- vispy/gloo/tests/test_util.py +60 -0
- vispy/gloo/tests/test_wrappers.py +261 -0
- vispy/gloo/texture.py +1046 -0
- vispy/gloo/util.py +129 -0
- vispy/gloo/wrappers.py +762 -0
- vispy/glsl/__init__.py +42 -0
- vispy/glsl/antialias/antialias.glsl +7 -0
- vispy/glsl/antialias/cap-butt.glsl +31 -0
- vispy/glsl/antialias/cap-round.glsl +29 -0
- vispy/glsl/antialias/cap-square.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
- vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
- vispy/glsl/antialias/cap.glsl +67 -0
- vispy/glsl/antialias/caps.glsl +67 -0
- vispy/glsl/antialias/filled.glsl +50 -0
- vispy/glsl/antialias/outline.glsl +40 -0
- vispy/glsl/antialias/stroke.glsl +43 -0
- vispy/glsl/arrowheads/angle.glsl +99 -0
- vispy/glsl/arrowheads/arrowheads.frag +60 -0
- vispy/glsl/arrowheads/arrowheads.glsl +12 -0
- vispy/glsl/arrowheads/arrowheads.vert +83 -0
- vispy/glsl/arrowheads/curved.glsl +48 -0
- vispy/glsl/arrowheads/inhibitor.glsl +26 -0
- vispy/glsl/arrowheads/stealth.glsl +46 -0
- vispy/glsl/arrowheads/triangle.glsl +97 -0
- vispy/glsl/arrowheads/util.glsl +13 -0
- vispy/glsl/arrows/angle-30.glsl +12 -0
- vispy/glsl/arrows/angle-60.glsl +12 -0
- vispy/glsl/arrows/angle-90.glsl +12 -0
- vispy/glsl/arrows/arrow.frag +39 -0
- vispy/glsl/arrows/arrow.vert +49 -0
- vispy/glsl/arrows/arrows.glsl +17 -0
- vispy/glsl/arrows/common.glsl +187 -0
- vispy/glsl/arrows/curved.glsl +63 -0
- vispy/glsl/arrows/stealth.glsl +50 -0
- vispy/glsl/arrows/triangle-30.glsl +12 -0
- vispy/glsl/arrows/triangle-60.glsl +12 -0
- vispy/glsl/arrows/triangle-90.glsl +12 -0
- vispy/glsl/arrows/util.glsl +98 -0
- vispy/glsl/build_spatial_filters.py +660 -0
- vispy/glsl/collections/agg-fast-path.frag +20 -0
- vispy/glsl/collections/agg-fast-path.vert +78 -0
- vispy/glsl/collections/agg-glyph.frag +60 -0
- vispy/glsl/collections/agg-glyph.vert +33 -0
- vispy/glsl/collections/agg-marker.frag +35 -0
- vispy/glsl/collections/agg-marker.vert +48 -0
- vispy/glsl/collections/agg-path.frag +55 -0
- vispy/glsl/collections/agg-path.vert +166 -0
- vispy/glsl/collections/agg-point.frag +21 -0
- vispy/glsl/collections/agg-point.vert +35 -0
- vispy/glsl/collections/agg-segment.frag +32 -0
- vispy/glsl/collections/agg-segment.vert +75 -0
- vispy/glsl/collections/marker.frag +38 -0
- vispy/glsl/collections/marker.vert +48 -0
- vispy/glsl/collections/raw-path.frag +15 -0
- vispy/glsl/collections/raw-path.vert +24 -0
- vispy/glsl/collections/raw-point.frag +14 -0
- vispy/glsl/collections/raw-point.vert +31 -0
- vispy/glsl/collections/raw-segment.frag +18 -0
- vispy/glsl/collections/raw-segment.vert +26 -0
- vispy/glsl/collections/raw-triangle.frag +13 -0
- vispy/glsl/collections/raw-triangle.vert +26 -0
- vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
- vispy/glsl/collections/sdf-glyph.frag +80 -0
- vispy/glsl/collections/sdf-glyph.vert +59 -0
- vispy/glsl/collections/tick-labels.vert +71 -0
- vispy/glsl/colormaps/autumn.glsl +20 -0
- vispy/glsl/colormaps/blues.glsl +20 -0
- vispy/glsl/colormaps/color-space.glsl +17 -0
- vispy/glsl/colormaps/colormaps.glsl +24 -0
- vispy/glsl/colormaps/cool.glsl +20 -0
- vispy/glsl/colormaps/fire.glsl +21 -0
- vispy/glsl/colormaps/gray.glsl +20 -0
- vispy/glsl/colormaps/greens.glsl +20 -0
- vispy/glsl/colormaps/hot.glsl +22 -0
- vispy/glsl/colormaps/ice.glsl +20 -0
- vispy/glsl/colormaps/icefire.glsl +23 -0
- vispy/glsl/colormaps/parse.py +40 -0
- vispy/glsl/colormaps/reds.glsl +20 -0
- vispy/glsl/colormaps/spring.glsl +20 -0
- vispy/glsl/colormaps/summer.glsl +20 -0
- vispy/glsl/colormaps/user.glsl +22 -0
- vispy/glsl/colormaps/util.glsl +41 -0
- vispy/glsl/colormaps/wheel.glsl +21 -0
- vispy/glsl/colormaps/winter.glsl +20 -0
- vispy/glsl/lines/agg.frag +320 -0
- vispy/glsl/lines/agg.vert +241 -0
- vispy/glsl/markers/arrow.glsl +12 -0
- vispy/glsl/markers/asterisk.glsl +16 -0
- vispy/glsl/markers/chevron.glsl +14 -0
- vispy/glsl/markers/clover.glsl +20 -0
- vispy/glsl/markers/club.glsl +31 -0
- vispy/glsl/markers/cross.glsl +17 -0
- vispy/glsl/markers/diamond.glsl +12 -0
- vispy/glsl/markers/disc.glsl +9 -0
- vispy/glsl/markers/ellipse.glsl +67 -0
- vispy/glsl/markers/hbar.glsl +9 -0
- vispy/glsl/markers/heart.glsl +15 -0
- vispy/glsl/markers/infinity.glsl +15 -0
- vispy/glsl/markers/marker-sdf.frag +74 -0
- vispy/glsl/markers/marker-sdf.vert +41 -0
- vispy/glsl/markers/marker.frag +36 -0
- vispy/glsl/markers/marker.vert +46 -0
- vispy/glsl/markers/markers.glsl +24 -0
- vispy/glsl/markers/pin.glsl +18 -0
- vispy/glsl/markers/ring.glsl +11 -0
- vispy/glsl/markers/spade.glsl +28 -0
- vispy/glsl/markers/square.glsl +10 -0
- vispy/glsl/markers/tag.glsl +11 -0
- vispy/glsl/markers/triangle.glsl +14 -0
- vispy/glsl/markers/vbar.glsl +9 -0
- vispy/glsl/math/circle-through-2-points.glsl +30 -0
- vispy/glsl/math/constants.glsl +48 -0
- vispy/glsl/math/double.glsl +114 -0
- vispy/glsl/math/functions.glsl +20 -0
- vispy/glsl/math/point-to-line-distance.glsl +31 -0
- vispy/glsl/math/point-to-line-projection.glsl +29 -0
- vispy/glsl/math/signed-line-distance.glsl +27 -0
- vispy/glsl/math/signed-segment-distance.glsl +30 -0
- vispy/glsl/misc/regular-grid.frag +244 -0
- vispy/glsl/misc/spatial-filters.frag +1407 -0
- vispy/glsl/misc/viewport-NDC.glsl +20 -0
- vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
- vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
- vispy/glsl/transforms/hammer.glsl +44 -0
- vispy/glsl/transforms/identity.glsl +6 -0
- vispy/glsl/transforms/identity_forward.glsl +23 -0
- vispy/glsl/transforms/identity_inverse.glsl +23 -0
- vispy/glsl/transforms/linear-scale.glsl +127 -0
- vispy/glsl/transforms/log-scale.glsl +126 -0
- vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
- vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
- vispy/glsl/transforms/panzoom.glsl +10 -0
- vispy/glsl/transforms/polar.glsl +41 -0
- vispy/glsl/transforms/position.glsl +44 -0
- vispy/glsl/transforms/power-scale.glsl +139 -0
- vispy/glsl/transforms/projection.glsl +7 -0
- vispy/glsl/transforms/pvm.glsl +13 -0
- vispy/glsl/transforms/rotate.glsl +45 -0
- vispy/glsl/transforms/trackball.glsl +15 -0
- vispy/glsl/transforms/translate.glsl +35 -0
- vispy/glsl/transforms/transverse_mercator.glsl +38 -0
- vispy/glsl/transforms/viewport-clipping.glsl +14 -0
- vispy/glsl/transforms/viewport-transform.glsl +16 -0
- vispy/glsl/transforms/viewport.glsl +50 -0
- vispy/glsl/transforms/x.glsl +24 -0
- vispy/glsl/transforms/y.glsl +19 -0
- vispy/glsl/transforms/z.glsl +14 -0
- vispy/io/__init__.py +20 -0
- vispy/io/_data/spatial-filters.npy +0 -0
- vispy/io/datasets.py +94 -0
- vispy/io/image.py +231 -0
- vispy/io/mesh.py +122 -0
- vispy/io/stl.py +167 -0
- vispy/io/tests/__init__.py +0 -0
- vispy/io/tests/test_image.py +47 -0
- vispy/io/tests/test_io.py +121 -0
- vispy/io/wavefront.py +350 -0
- vispy/plot/__init__.py +36 -0
- vispy/plot/fig.py +58 -0
- vispy/plot/plotwidget.py +522 -0
- vispy/plot/tests/__init__.py +0 -0
- vispy/plot/tests/test_plot.py +46 -0
- vispy/scene/__init__.py +43 -0
- vispy/scene/cameras/__init__.py +27 -0
- vispy/scene/cameras/_base.py +38 -0
- vispy/scene/cameras/arcball.py +105 -0
- vispy/scene/cameras/base_camera.py +551 -0
- vispy/scene/cameras/fly.py +474 -0
- vispy/scene/cameras/magnify.py +163 -0
- vispy/scene/cameras/panzoom.py +311 -0
- vispy/scene/cameras/perspective.py +338 -0
- vispy/scene/cameras/tests/__init__.py +0 -0
- vispy/scene/cameras/tests/test_cameras.py +27 -0
- vispy/scene/cameras/tests/test_link.py +53 -0
- vispy/scene/cameras/tests/test_perspective.py +122 -0
- vispy/scene/cameras/turntable.py +183 -0
- vispy/scene/canvas.py +639 -0
- vispy/scene/events.py +85 -0
- vispy/scene/node.py +644 -0
- vispy/scene/subscene.py +20 -0
- vispy/scene/tests/__init__.py +0 -0
- vispy/scene/tests/test_canvas.py +119 -0
- vispy/scene/tests/test_node.py +142 -0
- vispy/scene/tests/test_visuals.py +141 -0
- vispy/scene/visuals.py +276 -0
- vispy/scene/widgets/__init__.py +18 -0
- vispy/scene/widgets/anchor.py +25 -0
- vispy/scene/widgets/axis.py +88 -0
- vispy/scene/widgets/colorbar.py +176 -0
- vispy/scene/widgets/console.py +351 -0
- vispy/scene/widgets/grid.py +509 -0
- vispy/scene/widgets/label.py +50 -0
- vispy/scene/widgets/tests/__init__.py +0 -0
- vispy/scene/widgets/tests/test_colorbar.py +47 -0
- vispy/scene/widgets/viewbox.py +199 -0
- vispy/scene/widgets/widget.py +478 -0
- vispy/testing/__init__.py +51 -0
- vispy/testing/_runners.py +448 -0
- vispy/testing/_testing.py +416 -0
- vispy/testing/image_tester.py +494 -0
- vispy/testing/rendered_array_tester.py +85 -0
- vispy/testing/tests/__init__.py +0 -0
- vispy/testing/tests/test_testing.py +20 -0
- vispy/util/__init__.py +32 -0
- vispy/util/bunch.py +15 -0
- vispy/util/check_environment.py +57 -0
- vispy/util/config.py +490 -0
- vispy/util/dpi/__init__.py +19 -0
- vispy/util/dpi/_linux.py +69 -0
- vispy/util/dpi/_quartz.py +26 -0
- vispy/util/dpi/_win32.py +34 -0
- vispy/util/dpi/tests/__init__.py +0 -0
- vispy/util/dpi/tests/test_dpi.py +16 -0
- vispy/util/eq.py +41 -0
- vispy/util/event.py +774 -0
- vispy/util/fetching.py +276 -0
- vispy/util/filter.py +44 -0
- vispy/util/fonts/__init__.py +14 -0
- vispy/util/fonts/_freetype.py +73 -0
- vispy/util/fonts/_quartz.py +192 -0
- vispy/util/fonts/_triage.py +36 -0
- vispy/util/fonts/_vispy_fonts.py +20 -0
- vispy/util/fonts/_win32.py +105 -0
- vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
- vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
- vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
- vispy/util/fonts/tests/__init__.py +0 -0
- vispy/util/fonts/tests/test_font.py +45 -0
- vispy/util/fourier.py +69 -0
- vispy/util/frozen.py +25 -0
- vispy/util/gallery_scraper.py +268 -0
- vispy/util/keys.py +91 -0
- vispy/util/logs.py +358 -0
- vispy/util/osmesa_gl.py +17 -0
- vispy/util/profiler.py +135 -0
- vispy/util/ptime.py +16 -0
- vispy/util/quaternion.py +229 -0
- vispy/util/svg/__init__.py +18 -0
- vispy/util/svg/base.py +20 -0
- vispy/util/svg/color.py +219 -0
- vispy/util/svg/element.py +51 -0
- vispy/util/svg/geometry.py +478 -0
- vispy/util/svg/group.py +66 -0
- vispy/util/svg/length.py +81 -0
- vispy/util/svg/number.py +25 -0
- vispy/util/svg/path.py +332 -0
- vispy/util/svg/shapes.py +57 -0
- vispy/util/svg/style.py +59 -0
- vispy/util/svg/svg.py +40 -0
- vispy/util/svg/transform.py +223 -0
- vispy/util/svg/transformable.py +28 -0
- vispy/util/svg/viewport.py +73 -0
- vispy/util/tests/__init__.py +0 -0
- vispy/util/tests/test_config.py +58 -0
- vispy/util/tests/test_docstring_parameters.py +123 -0
- vispy/util/tests/test_emitter_group.py +262 -0
- vispy/util/tests/test_event_emitter.py +743 -0
- vispy/util/tests/test_fourier.py +35 -0
- vispy/util/tests/test_gallery_scraper.py +112 -0
- vispy/util/tests/test_import.py +127 -0
- vispy/util/tests/test_key.py +22 -0
- vispy/util/tests/test_logging.py +45 -0
- vispy/util/tests/test_run.py +14 -0
- vispy/util/tests/test_transforms.py +42 -0
- vispy/util/tests/test_vispy.py +48 -0
- vispy/util/transforms.py +201 -0
- vispy/util/wrappers.py +155 -0
- vispy/version.py +21 -0
- vispy/visuals/__init__.py +50 -0
- vispy/visuals/_scalable_textures.py +487 -0
- vispy/visuals/axis.py +678 -0
- vispy/visuals/border.py +208 -0
- vispy/visuals/box.py +79 -0
- vispy/visuals/collections/__init__.py +30 -0
- vispy/visuals/collections/agg_fast_path_collection.py +219 -0
- vispy/visuals/collections/agg_path_collection.py +197 -0
- vispy/visuals/collections/agg_point_collection.py +52 -0
- vispy/visuals/collections/agg_segment_collection.py +142 -0
- vispy/visuals/collections/array_list.py +401 -0
- vispy/visuals/collections/base_collection.py +482 -0
- vispy/visuals/collections/collection.py +253 -0
- vispy/visuals/collections/path_collection.py +23 -0
- vispy/visuals/collections/point_collection.py +19 -0
- vispy/visuals/collections/polygon_collection.py +25 -0
- vispy/visuals/collections/raw_path_collection.py +119 -0
- vispy/visuals/collections/raw_point_collection.py +113 -0
- vispy/visuals/collections/raw_polygon_collection.py +77 -0
- vispy/visuals/collections/raw_segment_collection.py +112 -0
- vispy/visuals/collections/raw_triangle_collection.py +78 -0
- vispy/visuals/collections/segment_collection.py +19 -0
- vispy/visuals/collections/triangle_collection.py +16 -0
- vispy/visuals/collections/util.py +168 -0
- vispy/visuals/colorbar.py +699 -0
- vispy/visuals/cube.py +41 -0
- vispy/visuals/ellipse.py +162 -0
- vispy/visuals/filters/__init__.py +10 -0
- vispy/visuals/filters/base_filter.py +242 -0
- vispy/visuals/filters/clipper.py +60 -0
- vispy/visuals/filters/clipping_planes.py +122 -0
- vispy/visuals/filters/color.py +181 -0
- vispy/visuals/filters/markers.py +28 -0
- vispy/visuals/filters/mesh.py +801 -0
- vispy/visuals/filters/picking.py +60 -0
- vispy/visuals/filters/tests/__init__.py +3 -0
- vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
- vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
- vispy/visuals/glsl/__init__.py +1 -0
- vispy/visuals/glsl/antialiasing.py +133 -0
- vispy/visuals/glsl/color.py +63 -0
- vispy/visuals/graphs/__init__.py +1 -0
- vispy/visuals/graphs/graph.py +240 -0
- vispy/visuals/graphs/layouts/__init__.py +55 -0
- vispy/visuals/graphs/layouts/circular.py +49 -0
- vispy/visuals/graphs/layouts/force_directed.py +211 -0
- vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
- vispy/visuals/graphs/layouts/random.py +52 -0
- vispy/visuals/graphs/tests/__init__.py +1 -0
- vispy/visuals/graphs/tests/test_layouts.py +139 -0
- vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
- vispy/visuals/graphs/util.py +120 -0
- vispy/visuals/gridlines.py +161 -0
- vispy/visuals/gridmesh.py +98 -0
- vispy/visuals/histogram.py +58 -0
- vispy/visuals/image.py +701 -0
- vispy/visuals/image_complex.py +130 -0
- vispy/visuals/infinite_line.py +199 -0
- vispy/visuals/instanced_mesh.py +152 -0
- vispy/visuals/isocurve.py +213 -0
- vispy/visuals/isoline.py +241 -0
- vispy/visuals/isosurface.py +113 -0
- vispy/visuals/line/__init__.py +6 -0
- vispy/visuals/line/arrow.py +289 -0
- vispy/visuals/line/dash_atlas.py +90 -0
- vispy/visuals/line/line.py +545 -0
- vispy/visuals/line_plot.py +135 -0
- vispy/visuals/linear_region.py +199 -0
- vispy/visuals/markers.py +819 -0
- vispy/visuals/mesh.py +373 -0
- vispy/visuals/mesh_normals.py +159 -0
- vispy/visuals/plane.py +54 -0
- vispy/visuals/polygon.py +145 -0
- vispy/visuals/rectangle.py +196 -0
- vispy/visuals/regular_polygon.py +56 -0
- vispy/visuals/scrolling_lines.py +197 -0
- vispy/visuals/shaders/__init__.py +17 -0
- vispy/visuals/shaders/compiler.py +206 -0
- vispy/visuals/shaders/expression.py +99 -0
- vispy/visuals/shaders/function.py +788 -0
- vispy/visuals/shaders/multiprogram.py +145 -0
- vispy/visuals/shaders/parsing.py +140 -0
- vispy/visuals/shaders/program.py +161 -0
- vispy/visuals/shaders/shader_object.py +162 -0
- vispy/visuals/shaders/tests/__init__.py +0 -0
- vispy/visuals/shaders/tests/test_function.py +486 -0
- vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
- vispy/visuals/shaders/tests/test_parsing.py +57 -0
- vispy/visuals/shaders/variable.py +272 -0
- vispy/visuals/spectrogram.py +169 -0
- vispy/visuals/sphere.py +80 -0
- vispy/visuals/surface_plot.py +192 -0
- vispy/visuals/tests/__init__.py +0 -0
- vispy/visuals/tests/test_arrows.py +109 -0
- vispy/visuals/tests/test_axis.py +120 -0
- vispy/visuals/tests/test_collections.py +15 -0
- vispy/visuals/tests/test_colorbar.py +179 -0
- vispy/visuals/tests/test_colormap.py +97 -0
- vispy/visuals/tests/test_ellipse.py +122 -0
- vispy/visuals/tests/test_gridlines.py +30 -0
- vispy/visuals/tests/test_histogram.py +24 -0
- vispy/visuals/tests/test_image.py +392 -0
- vispy/visuals/tests/test_image_complex.py +36 -0
- vispy/visuals/tests/test_infinite_line.py +53 -0
- vispy/visuals/tests/test_instanced_mesh.py +50 -0
- vispy/visuals/tests/test_isosurface.py +22 -0
- vispy/visuals/tests/test_linear_region.py +152 -0
- vispy/visuals/tests/test_markers.py +54 -0
- vispy/visuals/tests/test_mesh.py +261 -0
- vispy/visuals/tests/test_mesh_normals.py +218 -0
- vispy/visuals/tests/test_polygon.py +112 -0
- vispy/visuals/tests/test_rectangle.py +163 -0
- vispy/visuals/tests/test_regular_polygon.py +111 -0
- vispy/visuals/tests/test_scalable_textures.py +196 -0
- vispy/visuals/tests/test_sdf.py +73 -0
- vispy/visuals/tests/test_spectrogram.py +42 -0
- vispy/visuals/tests/test_surface_plot.py +57 -0
- vispy/visuals/tests/test_text.py +95 -0
- vispy/visuals/tests/test_volume.py +542 -0
- vispy/visuals/tests/test_windbarb.py +33 -0
- vispy/visuals/text/__init__.py +7 -0
- vispy/visuals/text/_sdf_cpu.cpython-313-darwin.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +112 -0
- vispy/visuals/text/_sdf_gpu.py +316 -0
- vispy/visuals/text/text.py +675 -0
- vispy/visuals/transforms/__init__.py +34 -0
- vispy/visuals/transforms/_util.py +191 -0
- vispy/visuals/transforms/base_transform.py +233 -0
- vispy/visuals/transforms/chain.py +300 -0
- vispy/visuals/transforms/interactive.py +98 -0
- vispy/visuals/transforms/linear.py +564 -0
- vispy/visuals/transforms/nonlinear.py +398 -0
- vispy/visuals/transforms/tests/__init__.py +0 -0
- vispy/visuals/transforms/tests/test_transforms.py +243 -0
- vispy/visuals/transforms/transform_system.py +339 -0
- vispy/visuals/tube.py +173 -0
- vispy/visuals/visual.py +923 -0
- vispy/visuals/volume.py +1366 -0
- vispy/visuals/windbarb.py +291 -0
- vispy/visuals/xyz_axis.py +34 -0
- vispy-0.15.0.dist-info/METADATA +243 -0
- vispy-0.15.0.dist-info/RECORD +521 -0
- vispy-0.15.0.dist-info/WHEEL +6 -0
- vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
- vispy-0.15.0.dist-info/top_level.txt +1 -0
vispy/gloo/__init__.py
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
3
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
4
|
+
|
|
5
|
+
"""
|
|
6
|
+
Object oriented interface to OpenGL.
|
|
7
|
+
|
|
8
|
+
This module implements classes for the things that are "objects" in
|
|
9
|
+
OpenGL, such as textures, FBO's, VBO's and shaders. Further, some
|
|
10
|
+
convenience classes are implemented (like the collection class).
|
|
11
|
+
|
|
12
|
+
This set of classes provides a friendly (Pythonic) interface
|
|
13
|
+
to OpenGL, and is designed to provide OpenGL's full functionality.
|
|
14
|
+
|
|
15
|
+
All classes inherit from GLObject, which provide a basic interface,
|
|
16
|
+
enabling, activating and deleting the object. Central to each
|
|
17
|
+
visualization is the Program. Other objects, such as Texture2D and
|
|
18
|
+
VertexBuffer should be set as uniforms and attributes of the Program
|
|
19
|
+
object.
|
|
20
|
+
|
|
21
|
+
Example::
|
|
22
|
+
|
|
23
|
+
# Init
|
|
24
|
+
program = gloo.Program(vertex_source, fragment_source)
|
|
25
|
+
program['a_position'] = gloo.VertexBuffer(my_positions_array)
|
|
26
|
+
program['s_texture'] = gloo.Texture2D(my_image)
|
|
27
|
+
...
|
|
28
|
+
|
|
29
|
+
# Draw event handler
|
|
30
|
+
program['u_color'] = 0.0, 1.0, 0.0
|
|
31
|
+
program.draw(gl.GL_TRIANGLES)
|
|
32
|
+
|
|
33
|
+
.. Note::
|
|
34
|
+
|
|
35
|
+
With vispy.gloo we strive to offer a Python interface that provides
|
|
36
|
+
the full functionality of OpenGL. However, this layer is a work in
|
|
37
|
+
progress and there are still a few known limitations. Most notably:
|
|
38
|
+
|
|
39
|
+
* TextureCubeMap is not yet implemented
|
|
40
|
+
* FBOs can only do 2D textures (not 3D textures or cube maps)
|
|
41
|
+
* No support for compressed textures.
|
|
42
|
+
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
from __future__ import division
|
|
46
|
+
|
|
47
|
+
from . import gl # noqa
|
|
48
|
+
from .wrappers import * # noqa
|
|
49
|
+
from .context import (GLContext, get_default_config, # noqa
|
|
50
|
+
get_current_canvas) # noqa
|
|
51
|
+
from .globject import GLObject # noqa
|
|
52
|
+
from .buffer import VertexBuffer, IndexBuffer # noqa
|
|
53
|
+
from .texture import Texture1D, Texture2D, TextureAtlas, Texture3D, TextureCube, TextureEmulated3D # noqa
|
|
54
|
+
from .program import Program # noqa
|
|
55
|
+
from .framebuffer import FrameBuffer, RenderBuffer # noqa
|
|
56
|
+
from . import util # noqa
|
vispy/gloo/buffer.py
ADDED
|
@@ -0,0 +1,505 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# -----------------------------------------------------------------------------
|
|
3
|
+
# Copyright (c) Vispy Development Team. All Rights Reserved.
|
|
4
|
+
# Distributed under the (new) BSD License. See LICENSE.txt for more info.
|
|
5
|
+
# -----------------------------------------------------------------------------
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
from os import path as op
|
|
9
|
+
from traceback import extract_stack, format_list
|
|
10
|
+
import weakref
|
|
11
|
+
|
|
12
|
+
from . globject import GLObject
|
|
13
|
+
from ..util import logger, np_copy_if_needed
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# ------------------------------------------------------------ Buffer class ---
|
|
17
|
+
class Buffer(GLObject):
|
|
18
|
+
"""Generic GPU buffer.
|
|
19
|
+
|
|
20
|
+
A generic buffer is an interface used to upload data to a GPU array buffer
|
|
21
|
+
(ARRAY_BUFFER or ELEMENT_ARRAY_BUFFER). It keeps track of
|
|
22
|
+
buffer size but does not have any CPU storage. You can consider it as
|
|
23
|
+
write-only.
|
|
24
|
+
|
|
25
|
+
The `set_data` is a deferred operation: you can call it even if an OpenGL
|
|
26
|
+
context is not available. The `update` function is responsible to upload
|
|
27
|
+
pending data to GPU memory and requires an active GL context.
|
|
28
|
+
|
|
29
|
+
The Buffer class only deals with data in terms of bytes; it is not
|
|
30
|
+
aware of data type or element size.
|
|
31
|
+
|
|
32
|
+
Parameters
|
|
33
|
+
----------
|
|
34
|
+
data : ndarray | None
|
|
35
|
+
Buffer data.
|
|
36
|
+
nbytes : int | None
|
|
37
|
+
Buffer byte size.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def __init__(self, data=None, nbytes=None):
|
|
41
|
+
GLObject.__init__(self)
|
|
42
|
+
self._views = weakref.WeakSet() # Views on this buffer
|
|
43
|
+
self._valid = True # To invalidate buffer views
|
|
44
|
+
self._nbytes = 0 # Bytesize in bytes, set in resize_bytes()
|
|
45
|
+
|
|
46
|
+
# Set data
|
|
47
|
+
if data is not None:
|
|
48
|
+
if nbytes is not None:
|
|
49
|
+
raise ValueError("Cannot specify both data and nbytes.")
|
|
50
|
+
self.set_data(data, copy=False)
|
|
51
|
+
elif nbytes is not None:
|
|
52
|
+
self.resize_bytes(nbytes)
|
|
53
|
+
|
|
54
|
+
@property
|
|
55
|
+
def nbytes(self):
|
|
56
|
+
"""Buffer size in bytes"""
|
|
57
|
+
return self._nbytes
|
|
58
|
+
|
|
59
|
+
def set_subdata(self, data, offset=0, copy=False):
|
|
60
|
+
"""Set a sub-region of the buffer (deferred operation).
|
|
61
|
+
|
|
62
|
+
Parameters
|
|
63
|
+
----------
|
|
64
|
+
data : ndarray
|
|
65
|
+
Data to be uploaded
|
|
66
|
+
offset: int
|
|
67
|
+
Offset in buffer where to start copying data (in bytes)
|
|
68
|
+
copy: bool
|
|
69
|
+
Since the operation is deferred, data may change before
|
|
70
|
+
data is actually uploaded to GPU memory.
|
|
71
|
+
Asking explicitly for a copy will prevent this behavior.
|
|
72
|
+
"""
|
|
73
|
+
data = np.array(data, copy=copy or np_copy_if_needed)
|
|
74
|
+
nbytes = data.nbytes
|
|
75
|
+
|
|
76
|
+
if offset < 0:
|
|
77
|
+
raise ValueError("Offset must be positive")
|
|
78
|
+
elif (offset + nbytes) > self._nbytes:
|
|
79
|
+
raise ValueError("Data does not fit into buffer")
|
|
80
|
+
|
|
81
|
+
# If the whole buffer is to be written, we clear any pending data
|
|
82
|
+
# (because they will be overwritten anyway)
|
|
83
|
+
if nbytes == self._nbytes and offset == 0:
|
|
84
|
+
self._glir.command('SIZE', self._id, nbytes)
|
|
85
|
+
self._glir.command('DATA', self._id, offset, data)
|
|
86
|
+
|
|
87
|
+
def set_data(self, data, copy=False):
|
|
88
|
+
"""Set data in the buffer (deferred operation).
|
|
89
|
+
|
|
90
|
+
This completely resets the size and contents of the buffer.
|
|
91
|
+
|
|
92
|
+
Parameters
|
|
93
|
+
----------
|
|
94
|
+
data : ndarray
|
|
95
|
+
Data to be uploaded
|
|
96
|
+
copy: bool
|
|
97
|
+
Since the operation is deferred, data may change before
|
|
98
|
+
data is actually uploaded to GPU memory.
|
|
99
|
+
Asking explicitly for a copy will prevent this behavior.
|
|
100
|
+
"""
|
|
101
|
+
data = np.array(data, copy=copy or np_copy_if_needed)
|
|
102
|
+
nbytes = data.nbytes
|
|
103
|
+
|
|
104
|
+
if nbytes != self._nbytes:
|
|
105
|
+
self.resize_bytes(nbytes)
|
|
106
|
+
else:
|
|
107
|
+
# Use SIZE to discard any previous data setting
|
|
108
|
+
self._glir.command('SIZE', self._id, nbytes)
|
|
109
|
+
|
|
110
|
+
if nbytes: # Only set data if there *is* data
|
|
111
|
+
self._glir.command('DATA', self._id, 0, data)
|
|
112
|
+
|
|
113
|
+
def resize_bytes(self, size):
|
|
114
|
+
"""Resize this buffer (deferred operation).
|
|
115
|
+
|
|
116
|
+
Parameters
|
|
117
|
+
----------
|
|
118
|
+
size : int
|
|
119
|
+
New buffer size in bytes.
|
|
120
|
+
"""
|
|
121
|
+
self._nbytes = size
|
|
122
|
+
self._glir.command('SIZE', self._id, size)
|
|
123
|
+
# Invalidate any view on this buffer
|
|
124
|
+
for view in self._views:
|
|
125
|
+
view._valid = False
|
|
126
|
+
self._views = weakref.WeakSet()
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
# -------------------------------------------------------- DataBuffer class ---
|
|
130
|
+
class DataBuffer(Buffer):
|
|
131
|
+
"""GPU data buffer that is aware of data type and elements size
|
|
132
|
+
|
|
133
|
+
Parameters
|
|
134
|
+
----------
|
|
135
|
+
data : ndarray | None
|
|
136
|
+
Buffer data.
|
|
137
|
+
"""
|
|
138
|
+
|
|
139
|
+
def __init__(self, data=None):
|
|
140
|
+
self._size = 0 # number of elements in buffer, set in resize_bytes()
|
|
141
|
+
self._dtype = None
|
|
142
|
+
self._stride = 0
|
|
143
|
+
self._itemsize = 0
|
|
144
|
+
self._last_dim = None
|
|
145
|
+
Buffer.__init__(self, data)
|
|
146
|
+
|
|
147
|
+
def _prepare_data(self, data):
|
|
148
|
+
# Can be overrriden by subclasses
|
|
149
|
+
if not isinstance(data, np.ndarray):
|
|
150
|
+
raise TypeError("DataBuffer data must be numpy array.")
|
|
151
|
+
return data
|
|
152
|
+
|
|
153
|
+
def set_subdata(self, data, offset=0, copy=False, **kwargs):
|
|
154
|
+
"""Set a sub-region of the buffer (deferred operation).
|
|
155
|
+
|
|
156
|
+
Parameters
|
|
157
|
+
----------
|
|
158
|
+
data : ndarray
|
|
159
|
+
Data to be uploaded
|
|
160
|
+
offset: int
|
|
161
|
+
Offset in buffer where to start copying data (i.e. index of
|
|
162
|
+
starting element).
|
|
163
|
+
copy: bool
|
|
164
|
+
Since the operation is deferred, data may change before
|
|
165
|
+
data is actually uploaded to GPU memory.
|
|
166
|
+
Asking explicitly for a copy will prevent this behavior.
|
|
167
|
+
**kwargs : dict
|
|
168
|
+
Additional keyword arguments.
|
|
169
|
+
|
|
170
|
+
"""
|
|
171
|
+
data = self._prepare_data(data, **kwargs)
|
|
172
|
+
offset = offset * self.itemsize
|
|
173
|
+
Buffer.set_subdata(self, data=data, offset=offset, copy=copy)
|
|
174
|
+
|
|
175
|
+
def set_data(self, data, copy=False, **kwargs):
|
|
176
|
+
"""Set data (deferred operation)
|
|
177
|
+
|
|
178
|
+
Parameters
|
|
179
|
+
----------
|
|
180
|
+
data : ndarray
|
|
181
|
+
Data to be uploaded
|
|
182
|
+
copy: bool
|
|
183
|
+
Since the operation is deferred, data may change before
|
|
184
|
+
data is actually uploaded to GPU memory.
|
|
185
|
+
Asking explicitly for a copy will prevent this behavior.
|
|
186
|
+
**kwargs : dict
|
|
187
|
+
Additional arguments.
|
|
188
|
+
"""
|
|
189
|
+
data = self._prepare_data(data, **kwargs)
|
|
190
|
+
self._dtype = data.dtype
|
|
191
|
+
# This works around some strange NumPy bug where a float32 array
|
|
192
|
+
# of shape (155407, 1) was said to have strides
|
|
193
|
+
# (4, 9223372036854775807), which is crazy
|
|
194
|
+
self._stride = data.strides[-1]
|
|
195
|
+
self._itemsize = self._dtype.itemsize
|
|
196
|
+
Buffer.set_data(self, data=data, copy=copy)
|
|
197
|
+
|
|
198
|
+
@property
|
|
199
|
+
def dtype(self):
|
|
200
|
+
"""Buffer dtype"""
|
|
201
|
+
return self._dtype
|
|
202
|
+
|
|
203
|
+
@property
|
|
204
|
+
def offset(self):
|
|
205
|
+
"""Buffer offset (in bytes) relative to base"""
|
|
206
|
+
return 0
|
|
207
|
+
|
|
208
|
+
@property
|
|
209
|
+
def stride(self):
|
|
210
|
+
"""Stride of data in memory"""
|
|
211
|
+
return self._stride
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
def size(self):
|
|
215
|
+
"""Number of elements in the buffer"""
|
|
216
|
+
return self._size
|
|
217
|
+
|
|
218
|
+
@property
|
|
219
|
+
def itemsize(self):
|
|
220
|
+
"""The total number of bytes required to store the array data"""
|
|
221
|
+
return self._itemsize
|
|
222
|
+
|
|
223
|
+
@property
|
|
224
|
+
def glsl_type(self):
|
|
225
|
+
"""GLSL declaration strings required for a variable to hold this data."""
|
|
226
|
+
if self.dtype is None:
|
|
227
|
+
return None
|
|
228
|
+
dtshape = self.dtype[0].shape
|
|
229
|
+
n = dtshape[0] if dtshape else 1
|
|
230
|
+
if n > 1:
|
|
231
|
+
dtype = 'vec%d' % n
|
|
232
|
+
else:
|
|
233
|
+
dtype = 'float' if 'f' in self.dtype[0].base.kind else 'int'
|
|
234
|
+
return 'attribute', dtype
|
|
235
|
+
|
|
236
|
+
def resize_bytes(self, size):
|
|
237
|
+
"""Resize the buffer (in-place, deferred operation)
|
|
238
|
+
|
|
239
|
+
Parameters
|
|
240
|
+
----------
|
|
241
|
+
size : integer
|
|
242
|
+
New buffer size in bytes
|
|
243
|
+
|
|
244
|
+
Notes
|
|
245
|
+
-----
|
|
246
|
+
This clears any pending operations.
|
|
247
|
+
"""
|
|
248
|
+
Buffer.resize_bytes(self, size)
|
|
249
|
+
self._size = size // self.itemsize
|
|
250
|
+
|
|
251
|
+
def __getitem__(self, key):
|
|
252
|
+
"""Create a view on this buffer."""
|
|
253
|
+
view = DataBufferView(self, key)
|
|
254
|
+
self._views.add(view)
|
|
255
|
+
return view
|
|
256
|
+
|
|
257
|
+
def __setitem__(self, key, data):
|
|
258
|
+
"""Set data (deferred operation)"""
|
|
259
|
+
# Setting a whole field of the buffer: only allowed if we have CPU
|
|
260
|
+
# storage. Note this case (key is string) only happen with base buffer
|
|
261
|
+
if isinstance(key, str):
|
|
262
|
+
raise ValueError("Cannot set non-contiguous data on buffer")
|
|
263
|
+
|
|
264
|
+
# Setting one or several elements
|
|
265
|
+
elif isinstance(key, int):
|
|
266
|
+
if key < 0:
|
|
267
|
+
key += self.size
|
|
268
|
+
if key < 0 or key > self.size:
|
|
269
|
+
raise IndexError("Buffer assignment index out of range")
|
|
270
|
+
start, stop, step = key, key + 1, 1
|
|
271
|
+
elif isinstance(key, slice):
|
|
272
|
+
start, stop, step = key.indices(self.size)
|
|
273
|
+
if stop < start:
|
|
274
|
+
start, stop = stop, start
|
|
275
|
+
elif key == Ellipsis:
|
|
276
|
+
start, stop, step = 0, self.size, 1
|
|
277
|
+
else:
|
|
278
|
+
raise TypeError("Buffer indices must be integers or strings")
|
|
279
|
+
|
|
280
|
+
# Contiguous update?
|
|
281
|
+
if step != 1:
|
|
282
|
+
raise ValueError("Cannot set non-contiguous data on buffer")
|
|
283
|
+
|
|
284
|
+
# Make sure data is an array
|
|
285
|
+
if not isinstance(data, np.ndarray):
|
|
286
|
+
data = np.array(data, dtype=self.dtype)
|
|
287
|
+
|
|
288
|
+
# Make sure data is big enough
|
|
289
|
+
if data.size < stop - start:
|
|
290
|
+
data = np.resize(data, stop - start)
|
|
291
|
+
elif data.size > stop - start:
|
|
292
|
+
raise ValueError('Data too big to fit GPU data '
|
|
293
|
+
'(%d > %d-%d).' % (data.size, stop, start))
|
|
294
|
+
|
|
295
|
+
# Set data
|
|
296
|
+
offset = start
|
|
297
|
+
self.set_subdata(data=data, offset=offset, copy=True)
|
|
298
|
+
|
|
299
|
+
def __repr__(self):
|
|
300
|
+
return ("<%s size=%s last_dim=%s>" %
|
|
301
|
+
(self.__class__.__name__, self.size, self._last_dim))
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
class DataBufferView(DataBuffer):
|
|
305
|
+
"""View on a sub-region of a DataBuffer.
|
|
306
|
+
|
|
307
|
+
Parameters
|
|
308
|
+
----------
|
|
309
|
+
base : DataBuffer
|
|
310
|
+
The buffer accessed by this view.
|
|
311
|
+
key : str, int, slice, or Ellpsis
|
|
312
|
+
The index into the base buffer that defines a sub-region of the buffer
|
|
313
|
+
to view. String arguments select a single field from multi-field
|
|
314
|
+
dtypes, and other allowed types select a subset of rows.
|
|
315
|
+
|
|
316
|
+
Notes
|
|
317
|
+
-----
|
|
318
|
+
It is generally not necessary to instantiate this class manually; use
|
|
319
|
+
``base_buffer[key]`` instead.
|
|
320
|
+
"""
|
|
321
|
+
|
|
322
|
+
# Note that this class is a bit evil: it is a subclass of GLObject,
|
|
323
|
+
# Buffer and DataBuffer, but any of these __init__'s are not called ...
|
|
324
|
+
|
|
325
|
+
def __init__(self, base, key):
|
|
326
|
+
# Note how this never runs the super's __init__,
|
|
327
|
+
# all attributes must thus be set here ...
|
|
328
|
+
|
|
329
|
+
self._base = base
|
|
330
|
+
self._key = key
|
|
331
|
+
self._stride = base.stride
|
|
332
|
+
|
|
333
|
+
if isinstance(key, str):
|
|
334
|
+
self._dtype = base.dtype[key]
|
|
335
|
+
self._offset = base.dtype.fields[key][1]
|
|
336
|
+
self._nbytes = base.size * self._dtype.itemsize
|
|
337
|
+
self._size = base.size
|
|
338
|
+
self._itemsize = self._dtype.itemsize
|
|
339
|
+
return
|
|
340
|
+
|
|
341
|
+
if isinstance(key, int):
|
|
342
|
+
if key < 0:
|
|
343
|
+
key += base.size
|
|
344
|
+
if key < 0 or key > base.size:
|
|
345
|
+
raise IndexError("Buffer assignment index out of range")
|
|
346
|
+
start, stop, step = key, key + 1, 1
|
|
347
|
+
elif isinstance(key, slice):
|
|
348
|
+
start, stop, step = key.indices(base.size)
|
|
349
|
+
if stop < start:
|
|
350
|
+
start, stop = stop, start
|
|
351
|
+
elif key == Ellipsis:
|
|
352
|
+
start, stop, step = 0, base.size, 1
|
|
353
|
+
else:
|
|
354
|
+
raise TypeError("Buffer indices must be integers or strings")
|
|
355
|
+
|
|
356
|
+
if step != 1:
|
|
357
|
+
raise ValueError("Cannot access non-contiguous data")
|
|
358
|
+
|
|
359
|
+
self._itemsize = base.itemsize
|
|
360
|
+
self._offset = start * self.itemsize
|
|
361
|
+
self._size = stop - start
|
|
362
|
+
self._dtype = base.dtype
|
|
363
|
+
self._nbytes = self.size * self.itemsize
|
|
364
|
+
|
|
365
|
+
@property
|
|
366
|
+
def glir(self):
|
|
367
|
+
return self._base.glir
|
|
368
|
+
|
|
369
|
+
@property
|
|
370
|
+
def id(self):
|
|
371
|
+
return self._base.id
|
|
372
|
+
|
|
373
|
+
@property
|
|
374
|
+
def _last_dim(self):
|
|
375
|
+
return self._base._last_dim
|
|
376
|
+
|
|
377
|
+
def set_subdata(self, data, offset=0, copy=False, **kwargs):
|
|
378
|
+
raise RuntimeError("Cannot set data on buffer view.")
|
|
379
|
+
|
|
380
|
+
def set_data(self, data, copy=False, **kwargs):
|
|
381
|
+
raise RuntimeError("Cannot set data on buffer view.")
|
|
382
|
+
|
|
383
|
+
@property
|
|
384
|
+
def offset(self):
|
|
385
|
+
"""Buffer offset (in bytes) relative to base"""
|
|
386
|
+
return self._offset
|
|
387
|
+
|
|
388
|
+
@property
|
|
389
|
+
def base(self):
|
|
390
|
+
"""Buffer base if this buffer is a view on another buffer."""
|
|
391
|
+
return self._base
|
|
392
|
+
|
|
393
|
+
def resize_bytes(self, size):
|
|
394
|
+
raise RuntimeError("Cannot resize buffer view.")
|
|
395
|
+
|
|
396
|
+
def __getitem__(self, key):
|
|
397
|
+
raise RuntimeError("Can only access data from a base buffer")
|
|
398
|
+
|
|
399
|
+
def __setitem__(self, key, data):
|
|
400
|
+
raise RuntimeError("Cannot set data on Buffer view")
|
|
401
|
+
|
|
402
|
+
def __repr__(self):
|
|
403
|
+
return ("<DataBufferView on %r at offset=%d size=%d>" %
|
|
404
|
+
(self.base, self.offset, self.size))
|
|
405
|
+
|
|
406
|
+
|
|
407
|
+
# ------------------------------------------------------ VertexBuffer class ---
|
|
408
|
+
class VertexBuffer(DataBuffer):
|
|
409
|
+
"""Buffer for vertex attribute data
|
|
410
|
+
|
|
411
|
+
Parameters
|
|
412
|
+
----------
|
|
413
|
+
data : ndarray
|
|
414
|
+
Buffer data (optional)
|
|
415
|
+
"""
|
|
416
|
+
|
|
417
|
+
def __init__(self, data=None, divisor=None):
|
|
418
|
+
super().__init__(data)
|
|
419
|
+
self.divisor = divisor
|
|
420
|
+
|
|
421
|
+
_GLIR_TYPE = 'VertexBuffer'
|
|
422
|
+
|
|
423
|
+
def _prepare_data(self, data, convert=False):
|
|
424
|
+
# Build a structured view of the data if:
|
|
425
|
+
# -> it is not already a structured array
|
|
426
|
+
# -> shape if 1-D or last dimension is 1,2,3 or 4
|
|
427
|
+
if isinstance(data, list):
|
|
428
|
+
data = np.array(data, dtype=np.float32)
|
|
429
|
+
if not isinstance(data, np.ndarray):
|
|
430
|
+
raise ValueError('Data must be a ndarray (got %s)' % type(data))
|
|
431
|
+
if data.dtype.isbuiltin:
|
|
432
|
+
if convert is True:
|
|
433
|
+
data = data.astype(np.float32)
|
|
434
|
+
if data.dtype in (np.float64, np.int64):
|
|
435
|
+
raise TypeError('data must be 32-bit not %s'
|
|
436
|
+
% data.dtype)
|
|
437
|
+
c = data.shape[-1] if data.ndim > 1 else 1
|
|
438
|
+
if c in [2, 3, 4]:
|
|
439
|
+
if not data.flags['C_CONTIGUOUS']:
|
|
440
|
+
logger.warning('Copying discontiguous data for struct '
|
|
441
|
+
'dtype:\n%s' % _last_stack_str())
|
|
442
|
+
data = data.copy()
|
|
443
|
+
else:
|
|
444
|
+
c = 1
|
|
445
|
+
if self._last_dim and c != self._last_dim:
|
|
446
|
+
raise ValueError('Last dimension should be %s not %s'
|
|
447
|
+
% (self._last_dim, c))
|
|
448
|
+
dtype_def = ('f0', data.dtype.base)
|
|
449
|
+
if c != 1:
|
|
450
|
+
# numpy dtypes with size 1 are ambiguous, only add size if it is greater than 1
|
|
451
|
+
dtype_def += (c,)
|
|
452
|
+
data = data.view(dtype=[dtype_def])
|
|
453
|
+
self._last_dim = c
|
|
454
|
+
return data
|
|
455
|
+
|
|
456
|
+
@property
|
|
457
|
+
def divisor(self):
|
|
458
|
+
return self._divisor
|
|
459
|
+
|
|
460
|
+
@divisor.setter
|
|
461
|
+
def divisor(self, value):
|
|
462
|
+
self._divisor = max(1, int(value)) if value else None
|
|
463
|
+
|
|
464
|
+
|
|
465
|
+
def _last_stack_str():
|
|
466
|
+
"""Print stack trace from call that didn't originate from here"""
|
|
467
|
+
stack = extract_stack()
|
|
468
|
+
for s in stack[::-1]:
|
|
469
|
+
if op.join('vispy', 'gloo', 'buffer.py') not in __file__:
|
|
470
|
+
break
|
|
471
|
+
return format_list([s])[0]
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
# ------------------------------------------------------- IndexBuffer class ---
|
|
475
|
+
class IndexBuffer(DataBuffer):
|
|
476
|
+
"""Buffer for index data
|
|
477
|
+
|
|
478
|
+
Parameters
|
|
479
|
+
----------
|
|
480
|
+
data : ndarray | None
|
|
481
|
+
Buffer data.
|
|
482
|
+
"""
|
|
483
|
+
|
|
484
|
+
_GLIR_TYPE = 'IndexBuffer'
|
|
485
|
+
|
|
486
|
+
def __init__(self, data=None):
|
|
487
|
+
DataBuffer.__init__(self, data)
|
|
488
|
+
self._last_dim = 1
|
|
489
|
+
|
|
490
|
+
def _prepare_data(self, data, convert=False):
|
|
491
|
+
if isinstance(data, list):
|
|
492
|
+
data = np.array(data, dtype=np.uint32)
|
|
493
|
+
if not isinstance(data, np.ndarray):
|
|
494
|
+
raise ValueError('Data must be a ndarray (got %s)' % type(data))
|
|
495
|
+
if not data.dtype.isbuiltin:
|
|
496
|
+
raise TypeError("Element buffer dtype cannot be structured")
|
|
497
|
+
else:
|
|
498
|
+
if convert:
|
|
499
|
+
if data.dtype is not np.uint32:
|
|
500
|
+
data = data.astype(np.uint32)
|
|
501
|
+
else:
|
|
502
|
+
if data.dtype not in [np.uint32, np.uint16, np.uint8]:
|
|
503
|
+
raise TypeError("Invalid dtype for IndexBuffer: %r" %
|
|
504
|
+
data.dtype)
|
|
505
|
+
return data
|