vispy 0.14.0__cp311-cp311-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 +968 -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 +1134 -0
- vispy/color/tests/__init__.py +0 -0
- vispy/color/tests/test_color.py +352 -0
- vispy/conftest.py +12 -0
- vispy/ext/__init__.py +0 -0
- vispy/ext/cocoapy.py +1542 -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 +134 -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 +698 -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 +506 -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 +566 -0
- vispy/gloo/gl/tests/test_names.py +246 -0
- vispy/gloo/gl/tests/test_use.py +71 -0
- vispy/gloo/glir.py +1816 -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 +1045 -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 +106 -0
- vispy/scene/cameras/base_camera.py +538 -0
- vispy/scene/cameras/fly.py +474 -0
- vispy/scene/cameras/magnify.py +163 -0
- vispy/scene/cameras/panzoom.py +308 -0
- vispy/scene/cameras/perspective.py +333 -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 +173 -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 +446 -0
- vispy/testing/_testing.py +416 -0
- vispy/testing/image_tester.py +473 -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 +17 -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 +4 -0
- vispy/visuals/__init__.py +50 -0
- vispy/visuals/_scalable_textures.py +485 -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 +163 -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 +796 -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 +105 -0
- vispy/visuals/gridmesh.py +98 -0
- vispy/visuals/histogram.py +58 -0
- vispy/visuals/image.py +688 -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 +810 -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_histogram.py +24 -0
- vispy/visuals/tests/test_image.py +390 -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 +180 -0
- vispy/visuals/tests/test_sdf.py +73 -0
- vispy/visuals/tests/test_spectrogram.py +42 -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-311-darwin.so +0 -0
- vispy/visuals/text/_sdf_cpu.pyx +110 -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 +1335 -0
- vispy/visuals/windbarb.py +291 -0
- vispy/visuals/xyz_axis.py +34 -0
- vispy-0.14.0.dist-info/LICENSE.txt +36 -0
- vispy-0.14.0.dist-info/METADATA +218 -0
- vispy-0.14.0.dist-info/RECORD +519 -0
- vispy-0.14.0.dist-info/WHEEL +5 -0
- vispy-0.14.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,119 @@
|
|
|
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
|
+
from vispy import gloo, scene
|
|
6
|
+
from vispy.testing import requires_application, TestingCanvas
|
|
7
|
+
from vispy.visuals.transforms import STTransform
|
|
8
|
+
|
|
9
|
+
import numpy as np
|
|
10
|
+
import pytest
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@requires_application()
|
|
14
|
+
@pytest.mark.parametrize(
|
|
15
|
+
'blend_func',
|
|
16
|
+
[
|
|
17
|
+
('src_alpha', 'one_minus_src_alpha', 'one', 'one_minus_src_alpha'),
|
|
18
|
+
('src_alpha', 'one_minus_src_alpha'),
|
|
19
|
+
None,
|
|
20
|
+
])
|
|
21
|
+
def test_canvas_render(blend_func):
|
|
22
|
+
"""Test rendering a canvas to an array.
|
|
23
|
+
|
|
24
|
+
Different blending functions are used to test what various Visuals may
|
|
25
|
+
produce without actually using different types of Visuals.
|
|
26
|
+
|
|
27
|
+
"""
|
|
28
|
+
with TestingCanvas(size=(125, 125), show=True, title='run') as c:
|
|
29
|
+
view = c.central_widget.add_view()
|
|
30
|
+
|
|
31
|
+
im1 = np.zeros((100, 100, 4)).astype(np.float32)
|
|
32
|
+
im1[:, :, 0] = 1
|
|
33
|
+
im1[:, :, 3] = 1
|
|
34
|
+
|
|
35
|
+
im2 = np.zeros((50, 50, 4)).astype(np.float32)
|
|
36
|
+
im2[:, :, 1] = 1
|
|
37
|
+
im2[:, :, 3] = 0.4
|
|
38
|
+
|
|
39
|
+
# Create the image
|
|
40
|
+
image1 = scene.visuals.Image(im1, parent=view.scene)
|
|
41
|
+
image1.transform = STTransform(translate=(20, 20, 0))
|
|
42
|
+
image2 = scene.visuals.Image(im2, parent=view.scene)
|
|
43
|
+
image2.transform = STTransform(translate=(0, 0, -1))
|
|
44
|
+
if blend_func:
|
|
45
|
+
image1.set_gl_state(preset='translucent', blend_func=blend_func)
|
|
46
|
+
image2.set_gl_state(preset='translucent', blend_func=blend_func)
|
|
47
|
+
|
|
48
|
+
rgba_result = c.render()
|
|
49
|
+
rgb_result = c.render(alpha=False)
|
|
50
|
+
|
|
51
|
+
# the results should be the same except for alpha
|
|
52
|
+
np.testing.assert_allclose(rgba_result[..., :3], rgb_result)
|
|
53
|
+
# the image should have something drawn in it
|
|
54
|
+
assert not np.allclose(rgba_result[..., :3], 0)
|
|
55
|
+
# the alpha should not be completely transparent
|
|
56
|
+
assert not np.allclose(rgba_result[..., 3], 0)
|
|
57
|
+
if blend_func is None or 'one' in blend_func:
|
|
58
|
+
# no transparency
|
|
59
|
+
np.testing.assert_allclose(rgba_result[..., 3], 255)
|
|
60
|
+
else:
|
|
61
|
+
# the alpha should have some transparency
|
|
62
|
+
assert (rgba_result[..., 3] != 255).any()
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
@requires_application()
|
|
66
|
+
def test_picking_basic():
|
|
67
|
+
"""Test basic picking behavior.
|
|
68
|
+
|
|
69
|
+
Based on https://github.com/vispy/vispy/issues/2107.
|
|
70
|
+
|
|
71
|
+
"""
|
|
72
|
+
with TestingCanvas(size=(125, 125), show=True, title='run') as c:
|
|
73
|
+
view = c.central_widget.add_view()
|
|
74
|
+
view.margin = 5 # add empty space where there are no visuals
|
|
75
|
+
view.camera = 'panzoom'
|
|
76
|
+
|
|
77
|
+
x = np.linspace(0, 400, 100)
|
|
78
|
+
y = np.linspace(0, 200, 100)
|
|
79
|
+
line = scene.Line(np.array((x, y)).T.astype(np.float32))
|
|
80
|
+
line.interactive = True
|
|
81
|
+
view.add(line)
|
|
82
|
+
view.camera.set_range()
|
|
83
|
+
|
|
84
|
+
c.render() # initial basic draw
|
|
85
|
+
for _ in range(2): # run picking twice to make sure it is repeatable
|
|
86
|
+
# get Visuals on a Canvas point that Line is drawn on
|
|
87
|
+
picked_visuals = c.visuals_at((100, 25))
|
|
88
|
+
assert len(picked_visuals) == 2
|
|
89
|
+
assert any(isinstance(vis, scene.ViewBox) for vis in picked_visuals)
|
|
90
|
+
assert any(isinstance(vis, scene.Line) for vis in picked_visuals)
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
@requires_application()
|
|
94
|
+
@pytest.mark.parametrize(
|
|
95
|
+
'preset',
|
|
96
|
+
[
|
|
97
|
+
'opaque', 'additive', 'translucent',
|
|
98
|
+
])
|
|
99
|
+
def test_blend_presets(preset):
|
|
100
|
+
"""Test blending presets render a canvas to an array.
|
|
101
|
+
|
|
102
|
+
Different blending presets are used to test that they properly set
|
|
103
|
+
blend equations.
|
|
104
|
+
|
|
105
|
+
"""
|
|
106
|
+
with TestingCanvas(size=(125, 125), show=True, title='run') as c:
|
|
107
|
+
view = c.central_widget.add_view()
|
|
108
|
+
im1 = np.zeros((100, 100, 4)).astype(np.float32)
|
|
109
|
+
im1[:, :, 1] = 1
|
|
110
|
+
im1[:, :, 3] = .4
|
|
111
|
+
# Create the image
|
|
112
|
+
image1 = scene.visuals.Image(im1, parent=view.scene)
|
|
113
|
+
image1.transform = STTransform(translate=(20, 20, -1))
|
|
114
|
+
|
|
115
|
+
gloo.set_state(blend_equation='min')
|
|
116
|
+
image1.set_gl_state(preset)
|
|
117
|
+
|
|
118
|
+
rgba_result = c.render()
|
|
119
|
+
assert not np.allclose(rgba_result[..., :3], 0)
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
from vispy.scene.node import Node
|
|
3
|
+
from vispy.testing import (requires_application, TestingCanvas,
|
|
4
|
+
run_tests_if_main, raises)
|
|
5
|
+
from vispy.visuals.transforms import STTransform
|
|
6
|
+
import numpy as np
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EventCheck(object):
|
|
10
|
+
def __init__(self, emitter):
|
|
11
|
+
self._events = []
|
|
12
|
+
self.emitter = emitter
|
|
13
|
+
emitter.connect(self.callback)
|
|
14
|
+
|
|
15
|
+
def callback(self, event):
|
|
16
|
+
self._events.append(event)
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def events(self):
|
|
20
|
+
ev = self._events
|
|
21
|
+
self._events = []
|
|
22
|
+
return ev
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
@requires_application()
|
|
26
|
+
def test_topology():
|
|
27
|
+
c = TestingCanvas()
|
|
28
|
+
assert c.scene.canvas is c
|
|
29
|
+
with raises(AttributeError):
|
|
30
|
+
c.foo = 'bar'
|
|
31
|
+
|
|
32
|
+
w = c.central_widget
|
|
33
|
+
assert w.parent is c.scene
|
|
34
|
+
assert w.scene_node is c.scene
|
|
35
|
+
assert w.document_node is c.scene
|
|
36
|
+
|
|
37
|
+
g = w.add_grid()
|
|
38
|
+
with raises(AttributeError):
|
|
39
|
+
g.foo = 'bar'
|
|
40
|
+
|
|
41
|
+
grid_check = EventCheck(g.events.children_change)
|
|
42
|
+
|
|
43
|
+
v1 = g.add_view(row=0, col=0)
|
|
44
|
+
assert v1.parent is g
|
|
45
|
+
assert v1.scene_node is c.scene
|
|
46
|
+
|
|
47
|
+
assert len(grid_check.events) == 1
|
|
48
|
+
|
|
49
|
+
v2 = g.add_view(row=1, col=0)
|
|
50
|
+
assert v2.parent is g
|
|
51
|
+
assert v2.scene_node is c.scene
|
|
52
|
+
assert v2.document_node is c.scene
|
|
53
|
+
|
|
54
|
+
assert len(grid_check.events) == 1
|
|
55
|
+
|
|
56
|
+
n1 = Node()
|
|
57
|
+
n1_parent_check = EventCheck(n1.events.parent_change)
|
|
58
|
+
n1_child_check = EventCheck(n1.events.children_change)
|
|
59
|
+
v1.add(n1)
|
|
60
|
+
assert len(n1_parent_check.events) == 1
|
|
61
|
+
assert n1.parent is v1.scene
|
|
62
|
+
assert n1.scene_node is v1.scene
|
|
63
|
+
assert n1.document_node is c.scene
|
|
64
|
+
|
|
65
|
+
n2 = Node(parent=n1)
|
|
66
|
+
n2_parent_check = EventCheck(n2.events.parent_change)
|
|
67
|
+
assert n2.parent is n1
|
|
68
|
+
assert n2.scene_node is v1.scene
|
|
69
|
+
assert n2.document_node is c.scene
|
|
70
|
+
assert len(n1_child_check.events) == 1
|
|
71
|
+
|
|
72
|
+
assert len(grid_check.events) == 2
|
|
73
|
+
|
|
74
|
+
v2.add(n1)
|
|
75
|
+
assert len(grid_check.events) == 2
|
|
76
|
+
assert len(n1_parent_check.events) == 1
|
|
77
|
+
assert len(n2_parent_check.events) == 1
|
|
78
|
+
assert n1.parent is v2.scene
|
|
79
|
+
assert n2.scene_node is v2.scene
|
|
80
|
+
assert n2.document_node is c.scene
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def test_transforms():
|
|
84
|
+
# test transform mapping between nodes
|
|
85
|
+
root = Node()
|
|
86
|
+
n1 = Node(parent=root)
|
|
87
|
+
n2 = Node(parent=n1)
|
|
88
|
+
n3 = Node(parent=root)
|
|
89
|
+
n4 = Node(parent=n3)
|
|
90
|
+
|
|
91
|
+
n1.transform = STTransform(scale=(0.1, 0.1), translate=(7, 6))
|
|
92
|
+
n2.transform = STTransform(scale=(0.2, 0.3), translate=(5, 4))
|
|
93
|
+
n3.transform = STTransform(scale=(0.4, 0.5), translate=(3, 2))
|
|
94
|
+
n4.transform = STTransform(scale=(0.6, 0.7), translate=(1, 0))
|
|
95
|
+
|
|
96
|
+
assert np.allclose(n1.transform.map((0, 0))[:2], (7, 6))
|
|
97
|
+
assert np.allclose(n1.node_transform(root).map((0, 0))[:2], (7, 6))
|
|
98
|
+
assert np.allclose(n2.transform.map((0, 0))[:2], (5, 4))
|
|
99
|
+
assert np.allclose(n2.node_transform(root).map((0, 0))[:2],
|
|
100
|
+
(5*0.1+7, 4*0.1+6))
|
|
101
|
+
assert np.allclose(root.node_transform(n1).map((0, 0))[:2],
|
|
102
|
+
(-7/0.1, -6/0.1))
|
|
103
|
+
assert np.allclose(root.node_transform(n2).map((0, 0))[:2],
|
|
104
|
+
((-7/0.1-5)/0.2, (-6/0.1-4)/0.3))
|
|
105
|
+
|
|
106
|
+
# just check that we can assemble transforms correctly mapping across the
|
|
107
|
+
# scenegraph
|
|
108
|
+
assert n2.node_path(n4) == ([n2, n1, root], [n3, n4])
|
|
109
|
+
assert n4.node_path(n2) == ([n4, n3, root], [n1, n2])
|
|
110
|
+
assert n2.node_path(root) == ([n2, n1, root], [])
|
|
111
|
+
assert root.node_path(n4) == ([root], [n3, n4])
|
|
112
|
+
assert n2.node_path_transforms(n4) == [n4.transform.inverse,
|
|
113
|
+
n3.transform.inverse,
|
|
114
|
+
n1.transform, n2.transform]
|
|
115
|
+
assert n4.node_path_transforms(n2) == [n2.transform.inverse,
|
|
116
|
+
n1.transform.inverse,
|
|
117
|
+
n3.transform, n4.transform]
|
|
118
|
+
|
|
119
|
+
pts = np.array([[0, 0], [1, 1], [-56.3, 800.2]])
|
|
120
|
+
assert np.all(n2.node_transform(n1).map(pts) == n2.transform.map(pts))
|
|
121
|
+
assert np.all(n2.node_transform(root).map(pts) ==
|
|
122
|
+
n1.transform.map(n2.transform.map(pts)))
|
|
123
|
+
assert np.all(n1.node_transform(n3).map(pts) ==
|
|
124
|
+
n3.transform.inverse.map(n1.transform.map(pts)))
|
|
125
|
+
assert np.all(n2.node_transform(n3).map(pts) ==
|
|
126
|
+
n3.transform.inverse.map(
|
|
127
|
+
n1.transform.map(n2.transform.map(pts))))
|
|
128
|
+
assert np.all(n2.node_transform(n4).map(pts) ==
|
|
129
|
+
n4.transform.inverse.map(n3.transform.inverse.map(
|
|
130
|
+
n1.transform.map(n2.transform.map(pts)))))
|
|
131
|
+
|
|
132
|
+
# test transforms still work after reparenting
|
|
133
|
+
n3.parent = n1
|
|
134
|
+
assert np.all(n2.node_transform(n4).map(pts) == n4.transform.inverse.map(
|
|
135
|
+
n3.transform.inverse.map(n2.transform.map(pts))))
|
|
136
|
+
|
|
137
|
+
# test transform simplification
|
|
138
|
+
assert np.all(n2.node_transform(n4).map(pts) ==
|
|
139
|
+
n2.node_transform(n4).simplified.map(pts))
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
run_tests_if_main()
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import pytest
|
|
2
|
+
|
|
3
|
+
from vispy.scene import visuals, Node
|
|
4
|
+
from vispy.scene.visuals import VisualNode
|
|
5
|
+
import vispy.visuals
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def test_docstrings():
|
|
9
|
+
# test that docstring insertions worked for all Visual+Node subclasses
|
|
10
|
+
for name in dir(visuals):
|
|
11
|
+
obj = getattr(visuals, name)
|
|
12
|
+
if isinstance(obj, type) and issubclass(obj, Node):
|
|
13
|
+
if obj is Node or obj is VisualNode:
|
|
14
|
+
continue
|
|
15
|
+
assert "This class inherits from visuals." in obj.__doc__
|
|
16
|
+
assert "parent : Node" in obj.__doc__
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
def test_visual_node_generation():
|
|
20
|
+
# test that all Visual classes also have Visual+Node classes
|
|
21
|
+
visuals = []
|
|
22
|
+
for name in dir(vispy.visuals):
|
|
23
|
+
obj = getattr(vispy.visuals, name)
|
|
24
|
+
if isinstance(obj, type) and issubclass(obj, Node):
|
|
25
|
+
if obj is Node:
|
|
26
|
+
continue
|
|
27
|
+
assert name.endswith('Visual')
|
|
28
|
+
vis_node = getattr(visuals, name[:-6])
|
|
29
|
+
assert issubclass(vis_node, Node)
|
|
30
|
+
assert issubclass(vis_node, obj)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_push_gl_state():
|
|
34
|
+
node = vispy.visuals.MeshVisual()
|
|
35
|
+
og_gl_state = node._vshare.gl_state.copy()
|
|
36
|
+
node.push_gl_state(blend=False, depth_test=False)
|
|
37
|
+
assert node._vshare.gl_state != og_gl_state
|
|
38
|
+
# preset is always set, unset kwargs should be absent
|
|
39
|
+
assert node._vshare.gl_state == {
|
|
40
|
+
"preset": None,
|
|
41
|
+
"blend": False,
|
|
42
|
+
"depth_test": False,
|
|
43
|
+
}
|
|
44
|
+
node.pop_gl_state()
|
|
45
|
+
assert node._vshare.gl_state == og_gl_state
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
def test_push_gl_state_update():
|
|
49
|
+
node = vispy.visuals.MeshVisual()
|
|
50
|
+
og_gl_state = node._vshare.gl_state.copy()
|
|
51
|
+
assert "blend" not in og_gl_state
|
|
52
|
+
assert node._vshare.gl_state["depth_test"]
|
|
53
|
+
|
|
54
|
+
node.push_gl_state_update(blend=False, depth_test=False)
|
|
55
|
+
assert node._vshare.gl_state != og_gl_state
|
|
56
|
+
assert not node._vshare.gl_state["blend"]
|
|
57
|
+
assert not node._vshare.gl_state["depth_test"]
|
|
58
|
+
|
|
59
|
+
node.pop_gl_state()
|
|
60
|
+
assert node._vshare.gl_state == og_gl_state
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
def test_pop_empty_gl_state():
|
|
64
|
+
node = vispy.visuals.MeshVisual()
|
|
65
|
+
assert node._prev_gl_state == []
|
|
66
|
+
og_gl_state = node._vshare.gl_state.copy()
|
|
67
|
+
node.pop_gl_state()
|
|
68
|
+
assert node._vshare.gl_state == og_gl_state
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def test_update_gl_state():
|
|
72
|
+
node = vispy.visuals.MeshVisual()
|
|
73
|
+
|
|
74
|
+
og_gl_state = node._vshare.gl_state.copy()
|
|
75
|
+
assert og_gl_state
|
|
76
|
+
og_gl_state["blend"] = False
|
|
77
|
+
|
|
78
|
+
node.update_gl_state(blend=True)
|
|
79
|
+
|
|
80
|
+
# check that the state was updated
|
|
81
|
+
assert node._vshare.gl_state.pop("blend") != og_gl_state.pop("blend")
|
|
82
|
+
# the rest of the state should be unchanged
|
|
83
|
+
assert node._vshare.gl_state == og_gl_state
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
def test_update_gl_state_context_manager():
|
|
87
|
+
node = vispy.visuals.MeshVisual()
|
|
88
|
+
|
|
89
|
+
node.set_gl_state(blend=False)
|
|
90
|
+
og_gl_state = node._vshare.gl_state.copy()
|
|
91
|
+
|
|
92
|
+
with node.update_gl_state(blend=True):
|
|
93
|
+
# check that the state was updated
|
|
94
|
+
assert node._vshare.gl_state == {**og_gl_state, "blend": True}
|
|
95
|
+
|
|
96
|
+
# the update should be reverted once out of the context
|
|
97
|
+
assert node._vshare.gl_state == og_gl_state
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def test_set_gl_state():
|
|
101
|
+
node = vispy.visuals.MeshVisual()
|
|
102
|
+
|
|
103
|
+
node.set_gl_state(blend=False, depth_test=False)
|
|
104
|
+
# preset is always set, unset kwargs should be absent
|
|
105
|
+
assert node._vshare.gl_state == {
|
|
106
|
+
"preset": None,
|
|
107
|
+
"blend": False,
|
|
108
|
+
"depth_test": False,
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
node.set_gl_state(blend=False)
|
|
112
|
+
# preset is always set, unset kwargs should be absent
|
|
113
|
+
assert node._vshare.gl_state == {"preset": None, "blend": False}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
def test_set_gl_state_context_manager():
|
|
117
|
+
node = vispy.visuals.MeshVisual()
|
|
118
|
+
|
|
119
|
+
node.set_gl_state(blend=False)
|
|
120
|
+
og_gl_state = node._vshare.gl_state.copy()
|
|
121
|
+
|
|
122
|
+
with node.set_gl_state(blend=True):
|
|
123
|
+
# preset is always set, unset kwargs should be absent
|
|
124
|
+
assert node._vshare.gl_state == {"preset": None, "blend": True}
|
|
125
|
+
|
|
126
|
+
# the update should be reverted once out of the context
|
|
127
|
+
assert node._vshare.gl_state == og_gl_state
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@pytest.mark.parametrize("enable_picking", [True, False])
|
|
131
|
+
def test_picking_context(enable_picking):
|
|
132
|
+
mesh = visuals.Mesh()
|
|
133
|
+
mesh.picking = not enable_picking
|
|
134
|
+
|
|
135
|
+
assert mesh.picking != enable_picking
|
|
136
|
+
|
|
137
|
+
with mesh.set_picking(picking=enable_picking) as p:
|
|
138
|
+
assert p == enable_picking
|
|
139
|
+
assert mesh.picking == enable_picking
|
|
140
|
+
|
|
141
|
+
assert mesh.picking != enable_picking
|
vispy/scene/visuals.py
ADDED
|
@@ -0,0 +1,276 @@
|
|
|
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
|
+
The classes in scene.visuals are visuals that may be added to a scenegraph
|
|
6
|
+
using the methods and properties defined in `vispy.scene.Node` such as name,
|
|
7
|
+
visible, parent, children, etc...
|
|
8
|
+
|
|
9
|
+
These classes are automatically generated by mixing `vispy.scene.Node` with
|
|
10
|
+
the Visual classes found in `vispy.visuals`.
|
|
11
|
+
|
|
12
|
+
For developing custom visuals, it is recommended to subclass from
|
|
13
|
+
`vispy.visuals.Visual` rather than `vispy.scene.Node`.
|
|
14
|
+
"""
|
|
15
|
+
import re
|
|
16
|
+
import weakref
|
|
17
|
+
|
|
18
|
+
from .. import visuals
|
|
19
|
+
from .node import Node
|
|
20
|
+
from ..visuals.filters import Alpha, PickingFilter
|
|
21
|
+
from typing import TypeVar
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
_T = TypeVar("_T")
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class VisualNode(Node):
|
|
28
|
+
_next_id = 1
|
|
29
|
+
_visual_ids = weakref.WeakValueDictionary()
|
|
30
|
+
|
|
31
|
+
def __init__(self, parent=None, name=None):
|
|
32
|
+
Node.__init__(self, parent=parent, name=name,
|
|
33
|
+
transforms=self.transforms)
|
|
34
|
+
self.interactive = False
|
|
35
|
+
self._opacity_filter = Alpha()
|
|
36
|
+
self.attach(self._opacity_filter)
|
|
37
|
+
|
|
38
|
+
self._id = VisualNode._next_id
|
|
39
|
+
VisualNode._visual_ids[self._id] = self
|
|
40
|
+
VisualNode._next_id += 1
|
|
41
|
+
self._picking_filter = PickingFilter(id_=self._id)
|
|
42
|
+
self.attach(self._picking_filter)
|
|
43
|
+
|
|
44
|
+
def _update_opacity(self):
|
|
45
|
+
self._opacity_filter.alpha = self._opacity
|
|
46
|
+
self.update()
|
|
47
|
+
|
|
48
|
+
def _set_clipper(self, node, clipper):
|
|
49
|
+
"""Assign a clipper that is inherited from a parent node.
|
|
50
|
+
|
|
51
|
+
If *clipper* is None, then remove any clippers for *node*.
|
|
52
|
+
"""
|
|
53
|
+
if node in self._clippers:
|
|
54
|
+
self.detach(self._clippers.pop(node))
|
|
55
|
+
if clipper is not None:
|
|
56
|
+
self.attach(clipper)
|
|
57
|
+
self._clippers[node] = clipper
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def picking(self):
|
|
61
|
+
"""Boolean that determines whether this node (and its children) are
|
|
62
|
+
drawn in picking mode.
|
|
63
|
+
"""
|
|
64
|
+
return self._picking
|
|
65
|
+
|
|
66
|
+
@picking.setter
|
|
67
|
+
def picking(self, p):
|
|
68
|
+
for c in self.children:
|
|
69
|
+
c.picking = p
|
|
70
|
+
if self._picking == p:
|
|
71
|
+
return
|
|
72
|
+
self._picking = p
|
|
73
|
+
self._picking_filter.enabled = p
|
|
74
|
+
if p:
|
|
75
|
+
self.push_gl_state_update(blend=False)
|
|
76
|
+
else:
|
|
77
|
+
self.pop_gl_state()
|
|
78
|
+
|
|
79
|
+
def _update_trsys(self, event):
|
|
80
|
+
"""Transform object(s) have changed for this Node; assign these to the
|
|
81
|
+
visual's TransformSystem.
|
|
82
|
+
"""
|
|
83
|
+
doc = self.document_node
|
|
84
|
+
scene = self.scene_node
|
|
85
|
+
root = self.root_node
|
|
86
|
+
self.transforms.visual_transform = self.node_transform(scene)
|
|
87
|
+
self.transforms.scene_transform = scene.node_transform(doc)
|
|
88
|
+
self.transforms.document_transform = doc.node_transform(root)
|
|
89
|
+
|
|
90
|
+
Node._update_trsys(self, event)
|
|
91
|
+
|
|
92
|
+
@property
|
|
93
|
+
def interactive(self):
|
|
94
|
+
"""Whether this widget should be allowed to accept mouse and touch
|
|
95
|
+
events.
|
|
96
|
+
"""
|
|
97
|
+
return self._interactive
|
|
98
|
+
|
|
99
|
+
@interactive.setter
|
|
100
|
+
def interactive(self, i):
|
|
101
|
+
self._interactive = i
|
|
102
|
+
|
|
103
|
+
def draw(self):
|
|
104
|
+
if self.picking and not self.interactive:
|
|
105
|
+
return
|
|
106
|
+
self._visual_superclass.draw(self)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def create_visual_node(subclass: _T) -> _T:
|
|
110
|
+
# Create a new subclass of Node.
|
|
111
|
+
|
|
112
|
+
# Decide on new class name
|
|
113
|
+
clsname = subclass.__name__
|
|
114
|
+
if not (clsname.endswith('Visual') and
|
|
115
|
+
issubclass(subclass, visuals.BaseVisual)):
|
|
116
|
+
raise RuntimeError('Class "%s" must end with Visual, and must '
|
|
117
|
+
'subclass BaseVisual' % clsname)
|
|
118
|
+
clsname = clsname[:-6]
|
|
119
|
+
|
|
120
|
+
# Generate new docstring based on visual docstring
|
|
121
|
+
try:
|
|
122
|
+
doc = generate_docstring(subclass, clsname)
|
|
123
|
+
except Exception:
|
|
124
|
+
# If parsing fails, just return the original Visual docstring
|
|
125
|
+
doc = subclass.__doc__
|
|
126
|
+
|
|
127
|
+
# New __init__ method
|
|
128
|
+
def __init__(self, *args, **kwargs):
|
|
129
|
+
parent = kwargs.pop('parent', None)
|
|
130
|
+
name = kwargs.pop('name', None)
|
|
131
|
+
self.name = name # to allow __str__ before Node.__init__
|
|
132
|
+
self._visual_superclass = subclass
|
|
133
|
+
|
|
134
|
+
subclass.__init__(self, *args, **kwargs)
|
|
135
|
+
self.unfreeze()
|
|
136
|
+
VisualNode.__init__(self, parent=parent, name=name)
|
|
137
|
+
self.freeze()
|
|
138
|
+
|
|
139
|
+
# Create new class
|
|
140
|
+
cls = type(clsname, (VisualNode, subclass),
|
|
141
|
+
{'__init__': __init__, '__doc__': doc})
|
|
142
|
+
|
|
143
|
+
return cls
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def generate_docstring(subclass, clsname):
|
|
147
|
+
# Generate a Visual+Node docstring by modifying the Visual's docstring
|
|
148
|
+
# to include information about Node inheritance and extra init args.
|
|
149
|
+
|
|
150
|
+
sc_doc = subclass.__doc__
|
|
151
|
+
if sc_doc is None:
|
|
152
|
+
sc_doc = ""
|
|
153
|
+
|
|
154
|
+
# find locations within docstring to insert new parameters
|
|
155
|
+
lines = sc_doc.split("\n")
|
|
156
|
+
|
|
157
|
+
# discard blank lines at start
|
|
158
|
+
while lines and lines[0].strip() == '':
|
|
159
|
+
lines.pop(0)
|
|
160
|
+
|
|
161
|
+
i = 0
|
|
162
|
+
params_started = False
|
|
163
|
+
param_indent = None
|
|
164
|
+
first_blank = None
|
|
165
|
+
param_end = None
|
|
166
|
+
while i < len(lines):
|
|
167
|
+
line = lines[i]
|
|
168
|
+
# ignore blank lines and '------' lines
|
|
169
|
+
if re.search(r'\w', line):
|
|
170
|
+
indent = len(line) - len(line.lstrip())
|
|
171
|
+
# If Params section has already started, check for end of params
|
|
172
|
+
# (that is where we will insert new params)
|
|
173
|
+
if params_started:
|
|
174
|
+
if indent < param_indent:
|
|
175
|
+
break
|
|
176
|
+
elif indent == param_indent:
|
|
177
|
+
# might be end of parameters block..
|
|
178
|
+
if re.match(r'\s*[a-zA-Z0-9_]+\s*:\s*\S+', line) is None:
|
|
179
|
+
break
|
|
180
|
+
param_end = i + 1
|
|
181
|
+
|
|
182
|
+
# Check for beginning of params section
|
|
183
|
+
elif re.match(r'\s*Parameters\s*', line):
|
|
184
|
+
params_started = True
|
|
185
|
+
param_indent = indent
|
|
186
|
+
if first_blank is None:
|
|
187
|
+
first_blank = i
|
|
188
|
+
|
|
189
|
+
# Check for first blank line
|
|
190
|
+
# (this is where the Node inheritance description will be
|
|
191
|
+
# inserted)
|
|
192
|
+
elif first_blank is None and line.strip() == '':
|
|
193
|
+
first_blank = i
|
|
194
|
+
|
|
195
|
+
i += 1
|
|
196
|
+
if i == len(lines) and param_end is None:
|
|
197
|
+
# reached end of docstring; insert here
|
|
198
|
+
param_end = i
|
|
199
|
+
|
|
200
|
+
# If original docstring has no params heading, we need to generate it.
|
|
201
|
+
if not params_started:
|
|
202
|
+
lines.extend(["", " Parameters", " ----------"])
|
|
203
|
+
param_end = len(lines)
|
|
204
|
+
if first_blank is None:
|
|
205
|
+
first_blank = param_end - 3
|
|
206
|
+
params_started = True
|
|
207
|
+
|
|
208
|
+
# build class and parameter description strings
|
|
209
|
+
class_desc = ("\n This class inherits from visuals.%sVisual and "
|
|
210
|
+
"scene.Node, allowing the visual to be placed inside a "
|
|
211
|
+
"scenegraph.\n" % (clsname))
|
|
212
|
+
parm_doc = (" parent : Node\n"
|
|
213
|
+
" The parent node to assign to this node (optional).\n"
|
|
214
|
+
" name : string\n"
|
|
215
|
+
" A name for this node, used primarily for debugging\n"
|
|
216
|
+
" (optional).")
|
|
217
|
+
|
|
218
|
+
# assemble all docstring parts
|
|
219
|
+
lines = (lines[:first_blank] +
|
|
220
|
+
[class_desc] +
|
|
221
|
+
lines[first_blank:param_end] +
|
|
222
|
+
[parm_doc] +
|
|
223
|
+
lines[param_end:])
|
|
224
|
+
|
|
225
|
+
doc = '\n'.join(lines)
|
|
226
|
+
return doc
|
|
227
|
+
|
|
228
|
+
# This is _not_ automated to help with auto-completion of IDEs,
|
|
229
|
+
# python REPL and IPython.
|
|
230
|
+
# Explicitly initializing these members allow IDEs to lookup
|
|
231
|
+
# and provide auto-completion. One problem is the fact that
|
|
232
|
+
# Docstrings are _not_ looked up correctly by IDEs, since they
|
|
233
|
+
# are attached programatically in the create_visual_node call.
|
|
234
|
+
# However, help(vispy.scene.FooVisual) still works
|
|
235
|
+
|
|
236
|
+
Arrow = create_visual_node(visuals.ArrowVisual)
|
|
237
|
+
Axis = create_visual_node(visuals.AxisVisual)
|
|
238
|
+
Box = create_visual_node(visuals.BoxVisual)
|
|
239
|
+
ColorBar = create_visual_node(visuals.ColorBarVisual)
|
|
240
|
+
Compound = create_visual_node(visuals.CompoundVisual)
|
|
241
|
+
Cube = create_visual_node(visuals.CubeVisual)
|
|
242
|
+
Ellipse = create_visual_node(visuals.EllipseVisual)
|
|
243
|
+
Graph = create_visual_node(visuals.GraphVisual)
|
|
244
|
+
GridLines = create_visual_node(visuals.GridLinesVisual)
|
|
245
|
+
GridMesh = create_visual_node(visuals.GridMeshVisual)
|
|
246
|
+
Histogram = create_visual_node(visuals.HistogramVisual)
|
|
247
|
+
Image = create_visual_node(visuals.ImageVisual)
|
|
248
|
+
ComplexImage = create_visual_node(visuals.ComplexImageVisual)
|
|
249
|
+
InfiniteLine = create_visual_node(visuals.InfiniteLineVisual)
|
|
250
|
+
InstancedMesh = create_visual_node(visuals.InstancedMeshVisual)
|
|
251
|
+
Isocurve = create_visual_node(visuals.IsocurveVisual)
|
|
252
|
+
Isoline = create_visual_node(visuals.IsolineVisual)
|
|
253
|
+
Isosurface = create_visual_node(visuals.IsosurfaceVisual)
|
|
254
|
+
Line = create_visual_node(visuals.LineVisual)
|
|
255
|
+
LinearRegion = create_visual_node(visuals.LinearRegionVisual)
|
|
256
|
+
LinePlot = create_visual_node(visuals.LinePlotVisual)
|
|
257
|
+
Markers = create_visual_node(visuals.MarkersVisual)
|
|
258
|
+
Mesh = create_visual_node(visuals.MeshVisual)
|
|
259
|
+
MeshNormals = create_visual_node(visuals.MeshNormalsVisual)
|
|
260
|
+
Plane = create_visual_node(visuals.PlaneVisual)
|
|
261
|
+
Polygon = create_visual_node(visuals.PolygonVisual)
|
|
262
|
+
Rectangle = create_visual_node(visuals.RectangleVisual)
|
|
263
|
+
RegularPolygon = create_visual_node(visuals.RegularPolygonVisual)
|
|
264
|
+
ScrollingLines = create_visual_node(visuals.ScrollingLinesVisual)
|
|
265
|
+
Spectrogram = create_visual_node(visuals.SpectrogramVisual)
|
|
266
|
+
Sphere = create_visual_node(visuals.SphereVisual)
|
|
267
|
+
SurfacePlot = create_visual_node(visuals.SurfacePlotVisual)
|
|
268
|
+
Text = create_visual_node(visuals.TextVisual)
|
|
269
|
+
Tube = create_visual_node(visuals.TubeVisual)
|
|
270
|
+
# Visual = create_visual_node(visuals.Visual) # Should not be created
|
|
271
|
+
Volume = create_visual_node(visuals.VolumeVisual)
|
|
272
|
+
Windbarb = create_visual_node(visuals.WindbarbVisual)
|
|
273
|
+
XYZAxis = create_visual_node(visuals.XYZAxisVisual)
|
|
274
|
+
|
|
275
|
+
__all__ = [name for (name, obj) in globals().items()
|
|
276
|
+
if isinstance(obj, type) and issubclass(obj, VisualNode)]
|
|
@@ -0,0 +1,18 @@
|
|
|
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
|
+
The vispy.scene.widgets namespace provides a range of widgets to allow
|
|
6
|
+
user interaction. Widgets are rectangular Visual objects such as buttons
|
|
7
|
+
and sliders.
|
|
8
|
+
"""
|
|
9
|
+
__all__ = ['AxisWidget', 'Console', 'ColorBarWidget', 'Grid',
|
|
10
|
+
'Label', 'ViewBox', 'Widget']
|
|
11
|
+
|
|
12
|
+
from .console import Console # noqa
|
|
13
|
+
from .grid import Grid # noqa
|
|
14
|
+
from .viewbox import ViewBox # noqa
|
|
15
|
+
from .widget import Widget # noqa
|
|
16
|
+
from .axis import AxisWidget # noqa
|
|
17
|
+
from .colorbar import ColorBarWidget # noqa
|
|
18
|
+
from .label import Label # noqa
|