vispy 0.15.0__cp313-cp313-macosx_11_0_arm64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of vispy might be problematic. Click here for more details.

Files changed (521) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +1003 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1213 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +378 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1522 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +162 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +700 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +594 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +568 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1824 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1046 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +105 -0
  274. vispy/scene/cameras/base_camera.py +551 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +311 -0
  278. vispy/scene/cameras/perspective.py +338 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +183 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +448 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +494 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +32 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +21 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +487 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +162 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +801 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +161 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +701 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +819 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_gridlines.py +30 -0
  477. vispy/visuals/tests/test_histogram.py +24 -0
  478. vispy/visuals/tests/test_image.py +392 -0
  479. vispy/visuals/tests/test_image_complex.py +36 -0
  480. vispy/visuals/tests/test_infinite_line.py +53 -0
  481. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  482. vispy/visuals/tests/test_isosurface.py +22 -0
  483. vispy/visuals/tests/test_linear_region.py +152 -0
  484. vispy/visuals/tests/test_markers.py +54 -0
  485. vispy/visuals/tests/test_mesh.py +261 -0
  486. vispy/visuals/tests/test_mesh_normals.py +218 -0
  487. vispy/visuals/tests/test_polygon.py +112 -0
  488. vispy/visuals/tests/test_rectangle.py +163 -0
  489. vispy/visuals/tests/test_regular_polygon.py +111 -0
  490. vispy/visuals/tests/test_scalable_textures.py +196 -0
  491. vispy/visuals/tests/test_sdf.py +73 -0
  492. vispy/visuals/tests/test_spectrogram.py +42 -0
  493. vispy/visuals/tests/test_surface_plot.py +57 -0
  494. vispy/visuals/tests/test_text.py +95 -0
  495. vispy/visuals/tests/test_volume.py +542 -0
  496. vispy/visuals/tests/test_windbarb.py +33 -0
  497. vispy/visuals/text/__init__.py +7 -0
  498. vispy/visuals/text/_sdf_cpu.cpython-313-darwin.so +0 -0
  499. vispy/visuals/text/_sdf_cpu.pyx +112 -0
  500. vispy/visuals/text/_sdf_gpu.py +316 -0
  501. vispy/visuals/text/text.py +675 -0
  502. vispy/visuals/transforms/__init__.py +34 -0
  503. vispy/visuals/transforms/_util.py +191 -0
  504. vispy/visuals/transforms/base_transform.py +233 -0
  505. vispy/visuals/transforms/chain.py +300 -0
  506. vispy/visuals/transforms/interactive.py +98 -0
  507. vispy/visuals/transforms/linear.py +564 -0
  508. vispy/visuals/transforms/nonlinear.py +398 -0
  509. vispy/visuals/transforms/tests/__init__.py +0 -0
  510. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  511. vispy/visuals/transforms/transform_system.py +339 -0
  512. vispy/visuals/tube.py +173 -0
  513. vispy/visuals/visual.py +923 -0
  514. vispy/visuals/volume.py +1366 -0
  515. vispy/visuals/windbarb.py +291 -0
  516. vispy/visuals/xyz_axis.py +34 -0
  517. vispy-0.15.0.dist-info/METADATA +243 -0
  518. vispy-0.15.0.dist-info/RECORD +521 -0
  519. vispy-0.15.0.dist-info/WHEEL +6 -0
  520. vispy-0.15.0.dist-info/licenses/LICENSE.txt +36 -0
  521. vispy-0.15.0.dist-info/top_level.txt +1 -0
@@ -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)