vispy 0.15.0__cp312-cp312-macosx_10_13_x86_64.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-312-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/visuals/markers.py
ADDED
|
@@ -0,0 +1,819 @@
|
|
|
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
|
+
"""Marker Visual and shader definitions."""
|
|
7
|
+
import numpy as np
|
|
8
|
+
|
|
9
|
+
from ..color import ColorArray
|
|
10
|
+
from ..gloo import VertexBuffer
|
|
11
|
+
from .shaders import Function, Variable
|
|
12
|
+
from .visual import Visual
|
|
13
|
+
from ..util.event import Event
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
_VERTEX_SHADER = """
|
|
17
|
+
uniform float u_antialias;
|
|
18
|
+
uniform float u_px_scale;
|
|
19
|
+
uniform bool u_scaling;
|
|
20
|
+
uniform bool u_spherical;
|
|
21
|
+
|
|
22
|
+
attribute vec3 a_position;
|
|
23
|
+
attribute vec4 a_fg_color;
|
|
24
|
+
attribute vec4 a_bg_color;
|
|
25
|
+
attribute float a_edgewidth;
|
|
26
|
+
attribute float a_size;
|
|
27
|
+
attribute float a_symbol;
|
|
28
|
+
|
|
29
|
+
varying vec4 v_fg_color;
|
|
30
|
+
varying vec4 v_bg_color;
|
|
31
|
+
varying float v_edgewidth;
|
|
32
|
+
varying float v_depth_middle;
|
|
33
|
+
varying float v_alias_ratio;
|
|
34
|
+
varying float v_symbol;
|
|
35
|
+
|
|
36
|
+
float big_float = 1e10; // prevents numerical imprecision
|
|
37
|
+
|
|
38
|
+
void main (void) {
|
|
39
|
+
v_fg_color = a_fg_color;
|
|
40
|
+
v_bg_color = a_bg_color;
|
|
41
|
+
// fluctuations can mess "fake integers" up, so we do +0.5 and floor to make sure it's right
|
|
42
|
+
v_symbol = a_symbol + 0.5;
|
|
43
|
+
|
|
44
|
+
vec4 pos = vec4(a_position, 1);
|
|
45
|
+
vec4 fb_pos = $visual_to_framebuffer(pos);
|
|
46
|
+
vec4 x;
|
|
47
|
+
vec4 size_vec;
|
|
48
|
+
gl_Position = $framebuffer_to_render(fb_pos);
|
|
49
|
+
|
|
50
|
+
// NOTE: gl_stuff uses framebuffer coords!
|
|
51
|
+
if (u_scaling) {
|
|
52
|
+
// scaling == "scene": scale marker using entire visual -> framebuffer set of transforms
|
|
53
|
+
// scaling == "visual": scale marker using only the Visual's transform
|
|
54
|
+
pos = $framebuffer_to_scene_or_visual(fb_pos);
|
|
55
|
+
x = $framebuffer_to_scene_or_visual(fb_pos + vec4(big_float, 0, 0, 0));
|
|
56
|
+
x = (x - pos);
|
|
57
|
+
// multiply that direction by the size and add it to the position
|
|
58
|
+
// this gives us the position of the edge of the point, which we convert in screen space
|
|
59
|
+
size_vec = $scene_or_visual_to_framebuffer(pos + normalize(x) * a_size);
|
|
60
|
+
// divide by `w` for perspective, and subtract pos
|
|
61
|
+
// this gives us the actual screen-space size of the point
|
|
62
|
+
$v_size = size_vec.x / size_vec.w - fb_pos.x / fb_pos.w;
|
|
63
|
+
v_edgewidth = ($v_size / a_size) * a_edgewidth;
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
// scaling == "fixed": marker is always the same number of pixels
|
|
67
|
+
$v_size = a_size * u_px_scale;
|
|
68
|
+
v_edgewidth = a_edgewidth * u_px_scale;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// gl_PointSize is the diameter
|
|
72
|
+
gl_PointSize = $v_size + 4. * (v_edgewidth + 1.5 * u_antialias);
|
|
73
|
+
|
|
74
|
+
if (u_spherical == true) {
|
|
75
|
+
// similar as above for scaling, but in towards the screen direction
|
|
76
|
+
// Get the framebuffer z direction relative to this sphere in visual coords
|
|
77
|
+
vec4 z = $framebuffer_to_scene_or_visual(fb_pos + vec4(0, 0, big_float, 0));
|
|
78
|
+
z = (z - pos);
|
|
79
|
+
// Get the depth of the sphere in its middle point on the screen
|
|
80
|
+
// size/2 because we need the radius, not the diameter
|
|
81
|
+
vec4 depth_z_vec = $scene_or_visual_to_framebuffer(pos + normalize(z) * a_size / 2);
|
|
82
|
+
v_depth_middle = depth_z_vec.z / depth_z_vec.w - fb_pos.z / fb_pos.w;
|
|
83
|
+
// size ratio between aliased and non-aliased, needed for correct depth
|
|
84
|
+
v_alias_ratio = gl_PointSize / $v_size;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
"""
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
_FRAGMENT_SHADER = """#version 120
|
|
91
|
+
uniform vec3 u_light_position;
|
|
92
|
+
uniform vec3 u_light_color;
|
|
93
|
+
uniform float u_light_ambient;
|
|
94
|
+
uniform float u_alpha;
|
|
95
|
+
uniform float u_antialias;
|
|
96
|
+
uniform bool u_spherical;
|
|
97
|
+
|
|
98
|
+
varying vec4 v_fg_color;
|
|
99
|
+
varying vec4 v_bg_color;
|
|
100
|
+
varying float v_edgewidth;
|
|
101
|
+
varying float v_depth_middle;
|
|
102
|
+
varying float v_alias_ratio;
|
|
103
|
+
varying float v_symbol;
|
|
104
|
+
|
|
105
|
+
void main()
|
|
106
|
+
{
|
|
107
|
+
// Discard plotting marker body and edge if zero-size
|
|
108
|
+
if ($v_size <= 0.)
|
|
109
|
+
discard;
|
|
110
|
+
|
|
111
|
+
float edgealphafactor = min(v_edgewidth, 1.0);
|
|
112
|
+
|
|
113
|
+
float size = $v_size + 4.*(v_edgewidth + 1.5*u_antialias);
|
|
114
|
+
// factor 6 for acute edge angles that need room as for star marker
|
|
115
|
+
|
|
116
|
+
// The marker function needs to be linked with this shader
|
|
117
|
+
float r = $marker(gl_PointCoord, size, int(v_symbol));
|
|
118
|
+
|
|
119
|
+
// it takes into account an antialising layer
|
|
120
|
+
// of size u_antialias inside the edge
|
|
121
|
+
// r:
|
|
122
|
+
// [-e/2-a, -e/2+a] antialising face-edge
|
|
123
|
+
// [-e/2+a, e/2-a] core edge (center 0, diameter e-2a = 2t)
|
|
124
|
+
// [e/2-a, e/2+a] antialising edge-background
|
|
125
|
+
// use max because we don't want negative transition zone
|
|
126
|
+
float t = max(0.5*v_edgewidth - u_antialias, 0);
|
|
127
|
+
float d = abs(r) - t;
|
|
128
|
+
|
|
129
|
+
if (r > 0.5*v_edgewidth + u_antialias)
|
|
130
|
+
{
|
|
131
|
+
// out of the marker (beyond the outer edge of the edge
|
|
132
|
+
// including transition zone due to antialiasing)
|
|
133
|
+
discard;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
vec4 facecolor = v_bg_color;
|
|
137
|
+
vec4 edgecolor = vec4(v_fg_color.rgb, edgealphafactor*v_fg_color.a);
|
|
138
|
+
float depth_change = 0;
|
|
139
|
+
|
|
140
|
+
// change color and depth if spherical mode is active
|
|
141
|
+
if (u_spherical == true) {
|
|
142
|
+
// multiply by alias_ratio and then clamp, so we're back to non-alias coordinates
|
|
143
|
+
// and the aliasing ring has the same coordinates as the point just inside,
|
|
144
|
+
// which is important for lighting
|
|
145
|
+
vec2 texcoord = (gl_PointCoord * 2 - 1) * v_alias_ratio;
|
|
146
|
+
float x = clamp(texcoord.x, -1, 1);
|
|
147
|
+
float y = clamp(texcoord.y, -1, 1);
|
|
148
|
+
float z = sqrt(clamp(1 - x*x - y*y, 0, 1));
|
|
149
|
+
vec3 normal = vec3(x, y, z);
|
|
150
|
+
|
|
151
|
+
// Diffuse color
|
|
152
|
+
float diffuse = dot(u_light_position, normal);
|
|
153
|
+
// clamp, because 0 < theta < pi/2
|
|
154
|
+
diffuse = clamp(diffuse, 0, 1);
|
|
155
|
+
vec3 diffuse_color = u_light_ambient + u_light_color * diffuse;
|
|
156
|
+
|
|
157
|
+
// Specular color
|
|
158
|
+
// reflect light wrt normal for the reflected ray, then
|
|
159
|
+
// find the angle made with the eye
|
|
160
|
+
vec3 eye = vec3(0, 0, -1);
|
|
161
|
+
float specular = dot(reflect(u_light_position, normal), eye);
|
|
162
|
+
specular = clamp(specular, 0, 1);
|
|
163
|
+
// raise to the material's shininess, multiply with a
|
|
164
|
+
// small factor for spread
|
|
165
|
+
specular = pow(specular, 80);
|
|
166
|
+
vec3 specular_color = u_light_color * specular;
|
|
167
|
+
|
|
168
|
+
facecolor = vec4(facecolor.rgb * diffuse_color + specular_color, facecolor.a * u_alpha);
|
|
169
|
+
edgecolor = vec4(edgecolor.rgb * diffuse_color + specular_color, edgecolor.a * u_alpha);
|
|
170
|
+
// TODO: figure out why this 0.5 is needed, despite already having the radius, not diameter
|
|
171
|
+
depth_change = -0.5 * z * v_depth_middle;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
if (d < 0.0)
|
|
175
|
+
{
|
|
176
|
+
// inside the width of the edge
|
|
177
|
+
// (core, out of the transition zone for antialiasing)
|
|
178
|
+
gl_FragColor = edgecolor;
|
|
179
|
+
}
|
|
180
|
+
else if (v_edgewidth == 0.)
|
|
181
|
+
{// no edge
|
|
182
|
+
if (r > -u_antialias)
|
|
183
|
+
{// outside
|
|
184
|
+
float alpha = 1.0 + r/u_antialias;
|
|
185
|
+
alpha = exp(-alpha*alpha);
|
|
186
|
+
gl_FragColor = vec4(facecolor.rgb, alpha*facecolor.a);
|
|
187
|
+
}
|
|
188
|
+
else
|
|
189
|
+
{// inside
|
|
190
|
+
gl_FragColor = facecolor;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
else
|
|
194
|
+
{// non-zero edge
|
|
195
|
+
float alpha = d/u_antialias;
|
|
196
|
+
alpha = exp(-alpha*alpha);
|
|
197
|
+
if (r > 0.)
|
|
198
|
+
{
|
|
199
|
+
// outer part of the edge: fade out into the background...
|
|
200
|
+
gl_FragColor = vec4(edgecolor.rgb, alpha*edgecolor.a);
|
|
201
|
+
}
|
|
202
|
+
else
|
|
203
|
+
{
|
|
204
|
+
// inner part of the edge: fade into the face color
|
|
205
|
+
gl_FragColor = mix(facecolor, edgecolor, alpha);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
gl_FragDepth = gl_FragCoord.z + depth_change;
|
|
209
|
+
}
|
|
210
|
+
"""
|
|
211
|
+
|
|
212
|
+
disc = """
|
|
213
|
+
float r = length((pointcoord.xy - vec2(0.5,0.5))*size);
|
|
214
|
+
r -= $v_size/2.;
|
|
215
|
+
return r;
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
|
|
219
|
+
arrow = """
|
|
220
|
+
const float sqrt2 = sqrt(2.);
|
|
221
|
+
float half_size = $v_size/2.;
|
|
222
|
+
float ady = abs(pointcoord.y -.5)*size;
|
|
223
|
+
float dx = (pointcoord.x -.5)*size;
|
|
224
|
+
float r1 = abs(dx) + ady - half_size;
|
|
225
|
+
float r2 = dx + 0.25*$v_size + ady - half_size;
|
|
226
|
+
float r = max(r1,-r2);
|
|
227
|
+
return r/sqrt2;//account for slanted edge and correct for width
|
|
228
|
+
"""
|
|
229
|
+
|
|
230
|
+
|
|
231
|
+
ring = """
|
|
232
|
+
float r1 = length((pointcoord.xy - vec2(0.5,0.5))*size) - $v_size/2.;
|
|
233
|
+
float r2 = length((pointcoord.xy - vec2(0.5,0.5))*size) - $v_size/4.;
|
|
234
|
+
float r = max(r1,-r2);
|
|
235
|
+
return r;
|
|
236
|
+
"""
|
|
237
|
+
|
|
238
|
+
clobber = """
|
|
239
|
+
const float sqrt3 = sqrt(3.);
|
|
240
|
+
const float PI = 3.14159265358979323846264;
|
|
241
|
+
const float t1 = -PI/2;
|
|
242
|
+
float circle_radius = 0.32 * $v_size;
|
|
243
|
+
float center_shift = 0.36/sqrt3 * $v_size;
|
|
244
|
+
//total size (horizontal) = 2*circle_radius + sqrt3*center_shirt = $v_size
|
|
245
|
+
vec2 c1 = vec2(cos(t1),sin(t1))*center_shift;
|
|
246
|
+
const float t2 = t1+2*PI/3;
|
|
247
|
+
vec2 c2 = vec2(cos(t2),sin(t2))*center_shift;
|
|
248
|
+
const float t3 = t2+2*PI/3;
|
|
249
|
+
vec2 c3 = vec2(cos(t3),sin(t3))*center_shift;
|
|
250
|
+
//xy is shift to center marker vertically
|
|
251
|
+
vec2 xy = (pointcoord.xy-vec2(0.5,0.5))*size + vec2(0.,-0.25*center_shift);
|
|
252
|
+
float r1 = length(xy - c1) - circle_radius;
|
|
253
|
+
float r2 = length(xy - c2) - circle_radius;
|
|
254
|
+
float r3 = length(xy - c3) - circle_radius;
|
|
255
|
+
float r = min(min(r1,r2),r3);
|
|
256
|
+
return r;
|
|
257
|
+
"""
|
|
258
|
+
|
|
259
|
+
|
|
260
|
+
square = """
|
|
261
|
+
float r = max(abs(pointcoord.x -.5)*size, abs(pointcoord.y -.5)*size);
|
|
262
|
+
r -= $v_size/2.;
|
|
263
|
+
return r;
|
|
264
|
+
"""
|
|
265
|
+
|
|
266
|
+
x = """
|
|
267
|
+
vec2 rotcoord = vec2((pointcoord.x + pointcoord.y - 1.) / sqrt(2.),
|
|
268
|
+
(pointcoord.y - pointcoord.x) / sqrt(2.));
|
|
269
|
+
//vbar
|
|
270
|
+
float r1 = abs(rotcoord.x)*size - $v_size/6.;
|
|
271
|
+
float r2 = abs(rotcoord.y)*size - $v_size/2.;
|
|
272
|
+
float vbar = max(r1,r2);
|
|
273
|
+
//hbar
|
|
274
|
+
float r3 = abs(rotcoord.y)*size - $v_size/6.;
|
|
275
|
+
float r4 = abs(rotcoord.x)*size - $v_size/2.;
|
|
276
|
+
float hbar = max(r3,r4);
|
|
277
|
+
return min(vbar, hbar);
|
|
278
|
+
"""
|
|
279
|
+
|
|
280
|
+
|
|
281
|
+
diamond = """
|
|
282
|
+
float r = abs(pointcoord.x -.5)*size + abs(pointcoord.y -.5)*size;
|
|
283
|
+
r -= $v_size/2.;
|
|
284
|
+
return r / sqrt(2.);//account for slanted edge and correct for width
|
|
285
|
+
"""
|
|
286
|
+
|
|
287
|
+
|
|
288
|
+
vbar = """
|
|
289
|
+
float r1 = abs(pointcoord.x - 0.5)*size - $v_size/6.;
|
|
290
|
+
float r3 = abs(pointcoord.y - 0.5)*size - $v_size/2.;
|
|
291
|
+
float r = max(r1,r3);
|
|
292
|
+
return r;
|
|
293
|
+
"""
|
|
294
|
+
|
|
295
|
+
hbar = """
|
|
296
|
+
float r2 = abs(pointcoord.y - 0.5)*size - $v_size/6.;
|
|
297
|
+
float r3 = abs(pointcoord.x - 0.5)*size - $v_size/2.;
|
|
298
|
+
float r = max(r2,r3);
|
|
299
|
+
return r;
|
|
300
|
+
"""
|
|
301
|
+
|
|
302
|
+
cross = """
|
|
303
|
+
//vbar
|
|
304
|
+
float r1 = abs(pointcoord.x - 0.5)*size - $v_size/6.;
|
|
305
|
+
float r2 = abs(pointcoord.y - 0.5)*size - $v_size/2.;
|
|
306
|
+
float vbar = max(r1,r2);
|
|
307
|
+
//hbar
|
|
308
|
+
float r3 = abs(pointcoord.y - 0.5)*size - $v_size/6.;
|
|
309
|
+
float r4 = abs(pointcoord.x - 0.5)*size - $v_size/2.;
|
|
310
|
+
float hbar = max(r3,r4);
|
|
311
|
+
return min(vbar, hbar);
|
|
312
|
+
"""
|
|
313
|
+
|
|
314
|
+
|
|
315
|
+
tailed_arrow = """
|
|
316
|
+
const float sqrt2 = sqrt(2.);
|
|
317
|
+
float half_size = $v_size/2.;
|
|
318
|
+
float ady = abs(pointcoord.y -.5)*size;
|
|
319
|
+
float dx = (pointcoord.x -.5)*size;
|
|
320
|
+
float r1 = abs(dx) + ady - half_size;
|
|
321
|
+
float r2 = dx + 0.25*$v_size + ady - half_size;
|
|
322
|
+
float arrow = max(r1,-r2);
|
|
323
|
+
//hbar
|
|
324
|
+
float upper_bottom_edges = ady - $v_size/8./sqrt2;
|
|
325
|
+
float left_edge = -dx - half_size;
|
|
326
|
+
float right_edge = dx + ady - half_size;
|
|
327
|
+
float hbar = max(upper_bottom_edges, left_edge);
|
|
328
|
+
float scale = 1.; //rescaling for slanted edge
|
|
329
|
+
if (right_edge >= hbar)
|
|
330
|
+
{
|
|
331
|
+
hbar = right_edge;
|
|
332
|
+
scale = sqrt2;
|
|
333
|
+
}
|
|
334
|
+
if (arrow <= hbar)
|
|
335
|
+
{
|
|
336
|
+
return arrow / sqrt2;//account for slanted edge and correct for width
|
|
337
|
+
}
|
|
338
|
+
else
|
|
339
|
+
{
|
|
340
|
+
return hbar / scale;
|
|
341
|
+
}
|
|
342
|
+
"""
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
triangle_up = """
|
|
346
|
+
float height = $v_size*sqrt(3.)/2.;
|
|
347
|
+
float bottom = ((pointcoord.y - 0.5)*size - height/2.);
|
|
348
|
+
float rotated_y = sqrt(3.)/2. * (pointcoord.x - 0.5) * size
|
|
349
|
+
- 0.5 * ((pointcoord.y - 0.5)*size - height/6.) + height/6.;
|
|
350
|
+
float right_edge = (rotated_y - height/2.);
|
|
351
|
+
float cc_rotated_y = -sqrt(3.)/2. * (pointcoord.x - 0.5)*size
|
|
352
|
+
- 0.5 * ((pointcoord.y - 0.5)*size - height/6.) + height/6.;
|
|
353
|
+
float left_edge = (cc_rotated_y - height/2.);
|
|
354
|
+
float slanted_edges = max(right_edge, left_edge);
|
|
355
|
+
return max(slanted_edges, bottom);
|
|
356
|
+
"""
|
|
357
|
+
|
|
358
|
+
triangle_down = """
|
|
359
|
+
float height = -$v_size*sqrt(3.)/2.;
|
|
360
|
+
float bottom = -((pointcoord.y - 0.5)*size - height/2.);
|
|
361
|
+
float rotated_y = sqrt(3.)/2. * (pointcoord.x - 0.5) * size
|
|
362
|
+
- 0.5 * ((pointcoord.y - 0.5)*size - height/6.) + height/6.;
|
|
363
|
+
float right_edge = -(rotated_y - height/2.);
|
|
364
|
+
float cc_rotated_y = -sqrt(3.)/2. * (pointcoord.x - 0.5)*size
|
|
365
|
+
- 0.5 * ((pointcoord.y - 0.5)*size - height/6.) + height/6.;
|
|
366
|
+
float left_edge = -(cc_rotated_y - height/2.);
|
|
367
|
+
float slanted_edges = max(right_edge, left_edge);
|
|
368
|
+
return max(slanted_edges, bottom);
|
|
369
|
+
"""
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
star = """
|
|
373
|
+
float star = -10000.;
|
|
374
|
+
const float PI2_5 = 3.141592653589*2./5.;
|
|
375
|
+
const float PI2_20 = 3.141592653589/10.; //PI*2/20
|
|
376
|
+
// downwards shift to that the marker center is halfway vertically
|
|
377
|
+
// between the top of the upward spike (y = -v_size/2.)
|
|
378
|
+
// and the bottom of one of two downward spikes
|
|
379
|
+
// (y = +v_size/2.*cos(2.*pi/10.) approx +v_size/2.*0.8)
|
|
380
|
+
// center is at -v_size/2.*0.1
|
|
381
|
+
float shift_y = -0.05*$v_size;
|
|
382
|
+
// first spike upwards,
|
|
383
|
+
// rotate spike by 72 deg four times to complete the star
|
|
384
|
+
for (int i = 0; i <= 4; i++)
|
|
385
|
+
{
|
|
386
|
+
//if not the first spike, rotate it upwards
|
|
387
|
+
float x = (pointcoord.x - 0.5)*size;
|
|
388
|
+
float y = (pointcoord.y - 0.5)*size;
|
|
389
|
+
float spike_rot_angle = float(i) * PI2_5;
|
|
390
|
+
float cosangle = cos(spike_rot_angle);
|
|
391
|
+
float sinangle = sin(spike_rot_angle);
|
|
392
|
+
float spike_x = x;
|
|
393
|
+
float spike_y = y + shift_y;
|
|
394
|
+
if (i > 0)
|
|
395
|
+
{
|
|
396
|
+
spike_x = cosangle * x - sinangle * (y + shift_y);
|
|
397
|
+
spike_y = sinangle * x + cosangle * (y + shift_y);
|
|
398
|
+
}
|
|
399
|
+
// in the frame where the spike is upwards:
|
|
400
|
+
// rotate 18 deg the zone x < 0 around the top of the star
|
|
401
|
+
// (point whose coords are -s/2, 0 where s is the size of the marker)
|
|
402
|
+
// compute y coordonates as well because
|
|
403
|
+
// we do a second rotation to put the spike at its final position
|
|
404
|
+
float rot_center_y = -$v_size/2.;
|
|
405
|
+
float rot18x = cos(PI2_20) * spike_x
|
|
406
|
+
- sin(PI2_20) * (spike_y - rot_center_y);
|
|
407
|
+
//rotate -18 deg the zone x > 0 arount the top of the star
|
|
408
|
+
float rot_18x = cos(PI2_20) * spike_x
|
|
409
|
+
+ sin(PI2_20) * (spike_y - rot_center_y);
|
|
410
|
+
float bottom = spike_y - $v_size/10.;
|
|
411
|
+
// max(left edge, right edge)
|
|
412
|
+
float spike = max(bottom, max(rot18x, -rot_18x));
|
|
413
|
+
if (i == 0)
|
|
414
|
+
{// first spike, skip the rotation
|
|
415
|
+
star = spike;
|
|
416
|
+
}
|
|
417
|
+
else // i > 0
|
|
418
|
+
{
|
|
419
|
+
star = min(star, spike);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
return star;
|
|
423
|
+
"""
|
|
424
|
+
|
|
425
|
+
cross_lines = """
|
|
426
|
+
//vbar
|
|
427
|
+
float r1 = abs(pointcoord.x - 0.5)*size;
|
|
428
|
+
float r2 = abs(pointcoord.y - 0.5)*size - $v_size/2;
|
|
429
|
+
float vbar = max(r1,r2);
|
|
430
|
+
//hbar
|
|
431
|
+
float r3 = abs(pointcoord.y - 0.5)*size;
|
|
432
|
+
float r4 = abs(pointcoord.x - 0.5)*size - $v_size/2;
|
|
433
|
+
float hbar = max(r3,r4);
|
|
434
|
+
return min(vbar, hbar);
|
|
435
|
+
"""
|
|
436
|
+
|
|
437
|
+
symbol_shaders = {
|
|
438
|
+
'disc': disc,
|
|
439
|
+
'arrow': arrow,
|
|
440
|
+
'ring': ring,
|
|
441
|
+
'clobber': clobber,
|
|
442
|
+
'square': square,
|
|
443
|
+
'x': x,
|
|
444
|
+
'diamond': diamond,
|
|
445
|
+
'vbar': vbar,
|
|
446
|
+
'hbar': hbar,
|
|
447
|
+
'cross': cross,
|
|
448
|
+
'tailed_arrow': tailed_arrow,
|
|
449
|
+
'triangle_up': triangle_up,
|
|
450
|
+
'triangle_down': triangle_down,
|
|
451
|
+
'star': star,
|
|
452
|
+
'cross_lines': cross_lines,
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
# combine all the symbol shaders in a big if-else statement
|
|
456
|
+
symbol_func = f"""
|
|
457
|
+
float symbol(vec2 pointcoord, float size, int symbol) {{
|
|
458
|
+
{' else'.join(
|
|
459
|
+
f''' if (symbol == {i}) {{
|
|
460
|
+
// {name}
|
|
461
|
+
{shader}
|
|
462
|
+
}}'''
|
|
463
|
+
for i, (name, shader) in enumerate(symbol_shaders.items())
|
|
464
|
+
)}
|
|
465
|
+
}}"""
|
|
466
|
+
|
|
467
|
+
# aliases
|
|
468
|
+
symbol_aliases = {
|
|
469
|
+
'o': 'disc',
|
|
470
|
+
'+': 'cross',
|
|
471
|
+
'++': 'cross_lines',
|
|
472
|
+
's': 'square',
|
|
473
|
+
'-': 'hbar',
|
|
474
|
+
'|': 'vbar',
|
|
475
|
+
'->': 'tailed_arrow',
|
|
476
|
+
'>': 'arrow',
|
|
477
|
+
'^': 'triangle_up',
|
|
478
|
+
'v': 'triangle_down',
|
|
479
|
+
'*': 'star',
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
symbol_shader_values = {name: i for i, name in enumerate(symbol_shaders)}
|
|
483
|
+
symbol_shader_values.update({
|
|
484
|
+
**{alias: symbol_shader_values[name] for alias, name in symbol_aliases.items()},
|
|
485
|
+
})
|
|
486
|
+
|
|
487
|
+
|
|
488
|
+
class MarkersVisual(Visual):
|
|
489
|
+
"""Visual displaying marker symbols.
|
|
490
|
+
|
|
491
|
+
Parameters
|
|
492
|
+
----------
|
|
493
|
+
pos : array
|
|
494
|
+
The array of locations to display each symbol.
|
|
495
|
+
size : float or array
|
|
496
|
+
The symbol size in screen (or data, if scaling is on) px.
|
|
497
|
+
edge_width : float or array or None
|
|
498
|
+
The width of the symbol outline in screen (or data, if scaling is on) px.
|
|
499
|
+
Defaults to 1.0 if None or not provided and ``edge_width_rel`` is not
|
|
500
|
+
provided.
|
|
501
|
+
edge_width_rel : float or array or None
|
|
502
|
+
The width as a fraction of marker size. Can not be specified along with
|
|
503
|
+
edge_width. A ValueError will be raised if both are provided.
|
|
504
|
+
edge_color : Color | ColorArray
|
|
505
|
+
The color used to draw each symbol outline.
|
|
506
|
+
face_color : Color | ColorArray
|
|
507
|
+
The color used to draw each symbol interior.
|
|
508
|
+
symbol : str or array
|
|
509
|
+
The style of symbol used to draw each marker (see Notes).
|
|
510
|
+
scaling : str | bool
|
|
511
|
+
Scaling method of individual markers. If set to "fixed" (default) then
|
|
512
|
+
no scaling is done and markers will always be the same number of
|
|
513
|
+
pixels on the screen. If set to "scene" then the chain of transforms
|
|
514
|
+
from the Visual's transform to the transform mapping to the OpenGL
|
|
515
|
+
framebuffer are used to scaling the marker. This has the effect of the
|
|
516
|
+
marker staying the same size in the "scene" coordinate space and
|
|
517
|
+
changing size as the visualization is zoomed in and out. If set to
|
|
518
|
+
"visual" the marker is scaled only using the transform of the Visual
|
|
519
|
+
and not the rest of the scene/camera. This means that something like
|
|
520
|
+
a camera changing the view will not affect the size of the marker, but
|
|
521
|
+
the user can still scale it using the Visual's transform. For
|
|
522
|
+
backwards compatibility this can be set to the boolean ``False`` for
|
|
523
|
+
"fixed" or ``True`` for "scene".
|
|
524
|
+
alpha : float
|
|
525
|
+
The opacity level of the visual.
|
|
526
|
+
antialias : float
|
|
527
|
+
Antialiasing amount (in px).
|
|
528
|
+
spherical : bool
|
|
529
|
+
Whether to add a spherical effect on the marker using lighting.
|
|
530
|
+
light_color : Color | ColorArray
|
|
531
|
+
The color of the light used to create the spherical effect.
|
|
532
|
+
light_position : array
|
|
533
|
+
The coordinates of the light used to create the spherical effect.
|
|
534
|
+
light_ambient : float
|
|
535
|
+
The amount of ambient light used to create the spherical effect.
|
|
536
|
+
|
|
537
|
+
Notes
|
|
538
|
+
-----
|
|
539
|
+
Allowed style strings are: disc, arrow, ring, clobber, square, diamond,
|
|
540
|
+
vbar, hbar, cross, tailed_arrow, x, triangle_up, triangle_down,
|
|
541
|
+
and star.
|
|
542
|
+
"""
|
|
543
|
+
|
|
544
|
+
_shaders = {
|
|
545
|
+
'vertex': _VERTEX_SHADER,
|
|
546
|
+
'fragment': _FRAGMENT_SHADER,
|
|
547
|
+
}
|
|
548
|
+
_symbol_shader_values = symbol_shader_values
|
|
549
|
+
_symbol_shader = symbol_func
|
|
550
|
+
|
|
551
|
+
def __init__(self, scaling="fixed", alpha=1, antialias=1, spherical=False,
|
|
552
|
+
light_color='white', light_position=(1, -1, 1), light_ambient=0.3, **kwargs):
|
|
553
|
+
self._vbo = VertexBuffer()
|
|
554
|
+
self._data = None
|
|
555
|
+
self._scaling = "fixed"
|
|
556
|
+
|
|
557
|
+
Visual.__init__(self, vcode=self._shaders['vertex'], fcode=self._shaders['fragment'])
|
|
558
|
+
self._symbol_func = Function(self._symbol_shader)
|
|
559
|
+
self.shared_program.frag['marker'] = self._symbol_func
|
|
560
|
+
self._v_size_var = Variable('varying float v_size')
|
|
561
|
+
self.shared_program.vert['v_size'] = self._v_size_var
|
|
562
|
+
self.shared_program.frag['v_size'] = self._v_size_var
|
|
563
|
+
self._symbol_func['v_size'] = self._v_size_var
|
|
564
|
+
|
|
565
|
+
self.set_gl_state(depth_test=True, blend=True,
|
|
566
|
+
blend_func=('src_alpha', 'one_minus_src_alpha'))
|
|
567
|
+
self._draw_mode = 'points'
|
|
568
|
+
|
|
569
|
+
self.events.add(data_updated=Event)
|
|
570
|
+
|
|
571
|
+
if len(kwargs) > 0:
|
|
572
|
+
self.set_data(**kwargs)
|
|
573
|
+
|
|
574
|
+
self.scaling = scaling
|
|
575
|
+
self.antialias = antialias
|
|
576
|
+
self.light_color = light_color
|
|
577
|
+
self.light_position = light_position
|
|
578
|
+
self.light_ambient = light_ambient
|
|
579
|
+
self.alpha = alpha
|
|
580
|
+
self.spherical = spherical
|
|
581
|
+
|
|
582
|
+
self.freeze()
|
|
583
|
+
|
|
584
|
+
def set_data(self, pos=None, size=10., edge_width=None, edge_width_rel=None,
|
|
585
|
+
edge_color='black', face_color='white',
|
|
586
|
+
symbol='o'):
|
|
587
|
+
"""Set the data used to display this visual.
|
|
588
|
+
|
|
589
|
+
Parameters
|
|
590
|
+
----------
|
|
591
|
+
pos : array
|
|
592
|
+
The array of locations to display each symbol.
|
|
593
|
+
size : float or array
|
|
594
|
+
The symbol size in screen (or data, if scaling is on) px.
|
|
595
|
+
edge_width : float or array or None
|
|
596
|
+
The width of the symbol outline in screen (or data, if scaling is on) px.
|
|
597
|
+
Defaults to 1.0 if None or not provided and ``edge_width_rel`` is not
|
|
598
|
+
provided.
|
|
599
|
+
edge_width_rel : float or array or None
|
|
600
|
+
The width as a fraction of marker size. Can not be specified along with
|
|
601
|
+
edge_width. A ValueError will be raised if both are provided.
|
|
602
|
+
edge_color : Color | ColorArray
|
|
603
|
+
The color used to draw each symbol outline.
|
|
604
|
+
face_color : Color | ColorArray
|
|
605
|
+
The color used to draw each symbol interior.
|
|
606
|
+
symbol : str or array
|
|
607
|
+
The style of symbol used to draw each marker (see Notes).
|
|
608
|
+
"""
|
|
609
|
+
if edge_width is not None and edge_width_rel is not None:
|
|
610
|
+
raise ValueError("either edge_width or edge_width_rel "
|
|
611
|
+
"should be provided, not both")
|
|
612
|
+
elif edge_width is None and edge_width_rel is None:
|
|
613
|
+
edge_width = 1.0
|
|
614
|
+
|
|
615
|
+
if edge_width is not None:
|
|
616
|
+
edge_width = np.asarray(edge_width)
|
|
617
|
+
if np.any(edge_width < 0):
|
|
618
|
+
raise ValueError('edge_width cannot be negative')
|
|
619
|
+
else:
|
|
620
|
+
edge_width_rel = np.asarray(edge_width_rel)
|
|
621
|
+
if np.any(edge_width_rel < 0):
|
|
622
|
+
raise ValueError('edge_width_rel cannot be negative')
|
|
623
|
+
|
|
624
|
+
edge_color = ColorArray(edge_color).rgba
|
|
625
|
+
if len(edge_color) == 1:
|
|
626
|
+
edge_color = edge_color[0]
|
|
627
|
+
|
|
628
|
+
face_color = ColorArray(face_color).rgba
|
|
629
|
+
if len(face_color) == 1:
|
|
630
|
+
face_color = face_color[0]
|
|
631
|
+
|
|
632
|
+
if pos is not None:
|
|
633
|
+
assert (isinstance(pos, np.ndarray) and
|
|
634
|
+
pos.ndim == 2 and pos.shape[1] in (2, 3))
|
|
635
|
+
|
|
636
|
+
n = len(pos)
|
|
637
|
+
data = np.zeros(n, dtype=[('a_position', np.float32, 3),
|
|
638
|
+
('a_fg_color', np.float32, 4),
|
|
639
|
+
('a_bg_color', np.float32, 4),
|
|
640
|
+
('a_size', np.float32),
|
|
641
|
+
('a_edgewidth', np.float32),
|
|
642
|
+
('a_symbol', np.float32)])
|
|
643
|
+
data['a_fg_color'] = edge_color
|
|
644
|
+
data['a_bg_color'] = face_color
|
|
645
|
+
if edge_width is not None:
|
|
646
|
+
data['a_edgewidth'] = edge_width
|
|
647
|
+
else:
|
|
648
|
+
data['a_edgewidth'] = size * edge_width_rel
|
|
649
|
+
data['a_position'][:, :pos.shape[1]] = pos
|
|
650
|
+
data['a_size'] = size
|
|
651
|
+
|
|
652
|
+
if symbol is None:
|
|
653
|
+
data["a_symbol"] = np.array(None)
|
|
654
|
+
else:
|
|
655
|
+
if isinstance(symbol, str):
|
|
656
|
+
symbol = [symbol]
|
|
657
|
+
try:
|
|
658
|
+
data['a_symbol'] = np.array([self._symbol_shader_values[x] for x in symbol])
|
|
659
|
+
except KeyError:
|
|
660
|
+
raise ValueError(f'symbols must one of {self.symbols}')
|
|
661
|
+
|
|
662
|
+
self._data = data
|
|
663
|
+
self._vbo.set_data(data)
|
|
664
|
+
self.shared_program.bind(self._vbo)
|
|
665
|
+
|
|
666
|
+
self.events.data_updated()
|
|
667
|
+
self.update()
|
|
668
|
+
|
|
669
|
+
@property
|
|
670
|
+
def symbols(self):
|
|
671
|
+
return list(self._symbol_shader_values)
|
|
672
|
+
|
|
673
|
+
@property
|
|
674
|
+
def symbol(self):
|
|
675
|
+
if self._data is None:
|
|
676
|
+
return None
|
|
677
|
+
value_to_symbol = {v: k for k, v in self._symbol_shader_values.items()}
|
|
678
|
+
return np.vectorize(value_to_symbol.get)(self._data['a_symbol'])
|
|
679
|
+
|
|
680
|
+
@symbol.setter
|
|
681
|
+
def symbol(self, value):
|
|
682
|
+
if self._data is not None:
|
|
683
|
+
rec_to_kw = {
|
|
684
|
+
'a_position': 'pos',
|
|
685
|
+
'a_fg_color': 'edge_color',
|
|
686
|
+
'a_bg_color': 'face_color',
|
|
687
|
+
'a_size': 'size',
|
|
688
|
+
'a_edgewidth': 'edge_width',
|
|
689
|
+
'a_symbol': 'symbol',
|
|
690
|
+
}
|
|
691
|
+
kwargs = {kw: self._data[rec] for rec, kw in rec_to_kw.items()}
|
|
692
|
+
else:
|
|
693
|
+
kwargs = {}
|
|
694
|
+
kwargs['symbol'] = value
|
|
695
|
+
self.set_data(**kwargs)
|
|
696
|
+
|
|
697
|
+
@property
|
|
698
|
+
def scaling(self):
|
|
699
|
+
"""
|
|
700
|
+
If set to True, marker scales when rezooming.
|
|
701
|
+
"""
|
|
702
|
+
return self._scaling
|
|
703
|
+
|
|
704
|
+
@scaling.setter
|
|
705
|
+
def scaling(self, value):
|
|
706
|
+
scaling_modes = {
|
|
707
|
+
False: "fixed",
|
|
708
|
+
True: "scene",
|
|
709
|
+
"fixed": "fixed",
|
|
710
|
+
"scene": "scene",
|
|
711
|
+
"visual": "visual",
|
|
712
|
+
}
|
|
713
|
+
if value not in scaling_modes:
|
|
714
|
+
possible_options = ", ".join(repr(opt) for opt in scaling_modes)
|
|
715
|
+
raise ValueError(f"Unknown scaling option {value!r}, expected one of: {possible_options}")
|
|
716
|
+
self._scaling = scaling_modes[value]
|
|
717
|
+
self.shared_program['u_scaling'] = self._scaling != "fixed"
|
|
718
|
+
self.update()
|
|
719
|
+
|
|
720
|
+
@property
|
|
721
|
+
def antialias(self):
|
|
722
|
+
"""
|
|
723
|
+
Antialiasing amount (in px).
|
|
724
|
+
"""
|
|
725
|
+
return self._antialias
|
|
726
|
+
|
|
727
|
+
@antialias.setter
|
|
728
|
+
def antialias(self, value):
|
|
729
|
+
value = float(value)
|
|
730
|
+
self.shared_program['u_antialias'] = value
|
|
731
|
+
self._antialias = value
|
|
732
|
+
self.update()
|
|
733
|
+
|
|
734
|
+
@property
|
|
735
|
+
def light_position(self):
|
|
736
|
+
"""
|
|
737
|
+
The coordinates of the light used to create the spherical effect.
|
|
738
|
+
"""
|
|
739
|
+
return self._light_position
|
|
740
|
+
|
|
741
|
+
@light_position.setter
|
|
742
|
+
def light_position(self, value):
|
|
743
|
+
value = np.array(value)
|
|
744
|
+
self.shared_program['u_light_position'] = value / np.linalg.norm(value)
|
|
745
|
+
self._light_position = value
|
|
746
|
+
self.update()
|
|
747
|
+
|
|
748
|
+
@property
|
|
749
|
+
def light_ambient(self):
|
|
750
|
+
"""
|
|
751
|
+
The amount of ambient light used to create the spherical effect.
|
|
752
|
+
"""
|
|
753
|
+
return self._light_ambient
|
|
754
|
+
|
|
755
|
+
@light_ambient.setter
|
|
756
|
+
def light_ambient(self, value):
|
|
757
|
+
self.shared_program['u_light_ambient'] = value
|
|
758
|
+
self._light_ambient = value
|
|
759
|
+
self.update()
|
|
760
|
+
|
|
761
|
+
@property
|
|
762
|
+
def light_color(self):
|
|
763
|
+
"""
|
|
764
|
+
The color of the light used to create the spherical effect.
|
|
765
|
+
"""
|
|
766
|
+
return self._light_color
|
|
767
|
+
|
|
768
|
+
@light_color.setter
|
|
769
|
+
def light_color(self, value):
|
|
770
|
+
self.shared_program['u_light_color'] = ColorArray(value).rgb
|
|
771
|
+
self._light_color = value
|
|
772
|
+
self.update()
|
|
773
|
+
|
|
774
|
+
@property
|
|
775
|
+
def alpha(self):
|
|
776
|
+
"""
|
|
777
|
+
The opacity level of the visual.
|
|
778
|
+
"""
|
|
779
|
+
return self._alpha
|
|
780
|
+
|
|
781
|
+
@alpha.setter
|
|
782
|
+
def alpha(self, value):
|
|
783
|
+
self.shared_program['u_alpha'] = value
|
|
784
|
+
self._alpha = value
|
|
785
|
+
self.update()
|
|
786
|
+
|
|
787
|
+
@property
|
|
788
|
+
def spherical(self):
|
|
789
|
+
"""
|
|
790
|
+
Whether to add a spherical effect on the marker using lighting.
|
|
791
|
+
"""
|
|
792
|
+
return self._spherical
|
|
793
|
+
|
|
794
|
+
@spherical.setter
|
|
795
|
+
def spherical(self, value):
|
|
796
|
+
self.shared_program['u_spherical'] = value
|
|
797
|
+
self._spherical = value
|
|
798
|
+
self.update()
|
|
799
|
+
|
|
800
|
+
def _prepare_transforms(self, view):
|
|
801
|
+
view.view_program.vert['visual_to_framebuffer'] = view.get_transform('visual', 'framebuffer')
|
|
802
|
+
view.view_program.vert['framebuffer_to_render'] = view.get_transform('framebuffer', 'render')
|
|
803
|
+
scaling = view._scaling if view._scaling != "fixed" else "scene"
|
|
804
|
+
view.view_program.vert['framebuffer_to_scene_or_visual'] = view.get_transform('framebuffer', scaling)
|
|
805
|
+
view.view_program.vert['scene_or_visual_to_framebuffer'] = view.get_transform(scaling, 'framebuffer')
|
|
806
|
+
|
|
807
|
+
def _prepare_draw(self, view):
|
|
808
|
+
if self._data is None:
|
|
809
|
+
return False
|
|
810
|
+
view.view_program['u_px_scale'] = view.transforms.pixel_scale
|
|
811
|
+
|
|
812
|
+
def _compute_bounds(self, axis, view):
|
|
813
|
+
pos = self._data['a_position']
|
|
814
|
+
if pos is None:
|
|
815
|
+
return None
|
|
816
|
+
if pos.shape[1] > axis:
|
|
817
|
+
return (pos[:, axis].min(), pos[:, axis].max())
|
|
818
|
+
else:
|
|
819
|
+
return (0, 0)
|