vispy 0.14.0__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.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 (519) 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 +968 -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 +1134 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +352 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1542 -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 +134 -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 +698 -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 +506 -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 +566 -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 +1816 -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 +1045 -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 +106 -0
  274. vispy/scene/cameras/base_camera.py +538 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +308 -0
  278. vispy/scene/cameras/perspective.py +333 -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 +173 -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 +446 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +473 -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 +17 -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 +4 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +485 -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 +163 -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 +796 -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 +105 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +688 -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 +810 -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_histogram.py +24 -0
  477. vispy/visuals/tests/test_image.py +390 -0
  478. vispy/visuals/tests/test_image_complex.py +36 -0
  479. vispy/visuals/tests/test_infinite_line.py +53 -0
  480. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  481. vispy/visuals/tests/test_isosurface.py +22 -0
  482. vispy/visuals/tests/test_linear_region.py +152 -0
  483. vispy/visuals/tests/test_markers.py +54 -0
  484. vispy/visuals/tests/test_mesh.py +261 -0
  485. vispy/visuals/tests/test_mesh_normals.py +218 -0
  486. vispy/visuals/tests/test_polygon.py +112 -0
  487. vispy/visuals/tests/test_rectangle.py +163 -0
  488. vispy/visuals/tests/test_regular_polygon.py +111 -0
  489. vispy/visuals/tests/test_scalable_textures.py +180 -0
  490. vispy/visuals/tests/test_sdf.py +73 -0
  491. vispy/visuals/tests/test_spectrogram.py +42 -0
  492. vispy/visuals/tests/test_text.py +95 -0
  493. vispy/visuals/tests/test_volume.py +542 -0
  494. vispy/visuals/tests/test_windbarb.py +33 -0
  495. vispy/visuals/text/__init__.py +7 -0
  496. vispy/visuals/text/_sdf_cpu.cpython-312-aarch64-linux-gnu.so +0 -0
  497. vispy/visuals/text/_sdf_cpu.pyx +110 -0
  498. vispy/visuals/text/_sdf_gpu.py +316 -0
  499. vispy/visuals/text/text.py +675 -0
  500. vispy/visuals/transforms/__init__.py +34 -0
  501. vispy/visuals/transforms/_util.py +191 -0
  502. vispy/visuals/transforms/base_transform.py +233 -0
  503. vispy/visuals/transforms/chain.py +300 -0
  504. vispy/visuals/transforms/interactive.py +98 -0
  505. vispy/visuals/transforms/linear.py +564 -0
  506. vispy/visuals/transforms/nonlinear.py +398 -0
  507. vispy/visuals/transforms/tests/__init__.py +0 -0
  508. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  509. vispy/visuals/transforms/transform_system.py +339 -0
  510. vispy/visuals/tube.py +173 -0
  511. vispy/visuals/visual.py +923 -0
  512. vispy/visuals/volume.py +1335 -0
  513. vispy/visuals/windbarb.py +291 -0
  514. vispy/visuals/xyz_axis.py +34 -0
  515. vispy-0.14.0.dist-info/LICENSE.txt +36 -0
  516. vispy-0.14.0.dist-info/METADATA +218 -0
  517. vispy-0.14.0.dist-info/RECORD +519 -0
  518. vispy-0.14.0.dist-info/WHEEL +6 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
vispy/visuals/image.py ADDED
@@ -0,0 +1,688 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+ """Primitive 2D image visual class."""
5
+
6
+ from __future__ import division
7
+
8
+ import warnings
9
+
10
+ import numpy as np
11
+
12
+ from ..gloo import Texture2D, VertexBuffer
13
+ from ..color import get_colormap
14
+ from .shaders import Function, FunctionChain
15
+ from .transforms import NullTransform
16
+ from .visual import Visual
17
+ from ..io import load_spatial_filters
18
+ from ._scalable_textures import CPUScaledTexture2D, GPUScaledTexture2D
19
+
20
+
21
+ _VERTEX_SHADER = """
22
+ uniform int method; // 0=subdivide, 1=impostor
23
+ attribute vec2 a_position;
24
+ attribute vec2 a_texcoord;
25
+ varying vec2 v_texcoord;
26
+
27
+ void main() {
28
+ v_texcoord = a_texcoord;
29
+ gl_Position = $transform(vec4(a_position, 0., 1.));
30
+ }
31
+ """
32
+
33
+ _FRAGMENT_SHADER = """
34
+ uniform vec2 image_size;
35
+ uniform int method; // 0=subdivide, 1=impostor
36
+ uniform sampler2D u_texture;
37
+ varying vec2 v_texcoord;
38
+
39
+ vec4 map_local_to_tex(vec4 x) {
40
+ // Cast ray from 3D viewport to surface of image
41
+ // (if $transform does not affect z values, then this
42
+ // can be optimized as simply $transform.map(x) )
43
+ vec4 p1 = $transform(x);
44
+ vec4 p2 = $transform(x + vec4(0, 0, 0.5, 0));
45
+ p1 /= p1.w;
46
+ p2 /= p2.w;
47
+ vec4 d = p2 - p1;
48
+ float f = p2.z / d.z;
49
+ vec4 p3 = p2 - d * f;
50
+
51
+ // finally map local to texture coords
52
+ return vec4(p3.xy / image_size, 0, 1);
53
+ }
54
+
55
+
56
+ void main()
57
+ {
58
+ vec2 texcoord;
59
+ if( method == 0 ) {
60
+ texcoord = v_texcoord;
61
+ }
62
+ else {
63
+ // vertex shader outputs clip coordinates;
64
+ // fragment shader maps to texture coordinates
65
+ texcoord = map_local_to_tex(vec4(v_texcoord, 0, 1)).xy;
66
+ }
67
+
68
+ gl_FragColor = $color_transform($get_data(texcoord));
69
+ }
70
+ """ # noqa
71
+
72
+ _INTERPOLATION_TEMPLATE = """
73
+ #include "misc/spatial-filters.frag"
74
+ vec4 texture_lookup_filtered(vec2 texcoord) {
75
+ if(texcoord.x < 0.0 || texcoord.x > 1.0 ||
76
+ texcoord.y < 0.0 || texcoord.y > 1.0) {
77
+ discard;
78
+ }
79
+ return %s($texture, $shape, texcoord);
80
+ }"""
81
+
82
+ _TEXTURE_LOOKUP = """
83
+ vec4 texture_lookup(vec2 texcoord) {
84
+ if(texcoord.x < 0.0 || texcoord.x > 1.0 ||
85
+ texcoord.y < 0.0 || texcoord.y > 1.0) {
86
+ discard;
87
+ }
88
+ return texture2D($texture, texcoord);
89
+ }"""
90
+
91
+ _APPLY_CLIM_FLOAT = """
92
+ float apply_clim(float data) {
93
+ // If data is NaN, don't draw it at all
94
+ // http://stackoverflow.com/questions/11810158/how-to-deal-with-nan-or-inf-in-opengl-es-2-0-shaders
95
+ if (!(data <= 0.0 || 0.0 <= data)) {
96
+ discard;
97
+ }
98
+ data = clamp(data, min($clim.x, $clim.y), max($clim.x, $clim.y));
99
+ data = (data - $clim.x) / ($clim.y - $clim.x);
100
+ return data;
101
+ }"""
102
+
103
+ _APPLY_CLIM = """
104
+ vec4 apply_clim(vec4 color) {
105
+ // Handle NaN values
106
+ // http://stackoverflow.com/questions/11810158/how-to-deal-with-nan-or-inf-in-opengl-es-2-0-shaders
107
+ color.r = !(color.r <= 0.0 || 0.0 <= color.r) ? min($clim.x, $clim.y) : color.r;
108
+ color.g = !(color.g <= 0.0 || 0.0 <= color.g) ? min($clim.x, $clim.y) : color.g;
109
+ color.b = !(color.b <= 0.0 || 0.0 <= color.b) ? min($clim.x, $clim.y) : color.b;
110
+ color.a = !(color.a <= 0.0 || 0.0 <= color.a) ? 0 : color.a;
111
+ color.rgb = clamp(color.rgb, min($clim.x, $clim.y), max($clim.x, $clim.y));
112
+ color.rgb = (color.rgb - $clim.x) / ($clim.y - $clim.x);
113
+ return max(color, 0.0);
114
+ }
115
+ """
116
+
117
+ _APPLY_GAMMA_FLOAT = """
118
+ float apply_gamma(float data) {
119
+ return pow(data, $gamma);
120
+ }"""
121
+
122
+ _APPLY_GAMMA = """
123
+ vec4 apply_gamma(vec4 color) {
124
+ color.rgb = pow(color.rgb, vec3($gamma));
125
+ return color;
126
+ }
127
+ """
128
+
129
+ _NULL_COLOR_TRANSFORM = 'vec4 pass(vec4 color) { return color; }'
130
+
131
+ _C2L_RED = 'float cmap(vec4 color) { return color.r; }'
132
+
133
+ _CUSTOM_FILTER = """
134
+ vec4 texture_lookup(vec2 texcoord) {
135
+ // based on https://gist.github.com/kingbedjed/373c8811efcf1b3a155d29a13c1e5b61
136
+ vec2 tex_pixel = 1 / $shape;
137
+ vec2 kernel_pixel = 1 / $kernel_shape;
138
+ vec2 sampling_corner = texcoord - ($kernel_shape / 2 * tex_pixel);
139
+
140
+ // loop over kernel pixels
141
+ vec2 kernel_pos, tex_pos;
142
+ vec4 color = vec4(0);
143
+ float weight;
144
+
145
+ // offset 0.5 to sample center of pixels
146
+ for (float i = 0.5; i < $kernel_shape.x; i++) {
147
+ for (float j = 0.5; j < $kernel_shape.y; j++) {
148
+ kernel_pos = vec2(i, j) * kernel_pixel;
149
+ tex_pos = sampling_corner + vec2(i, j) * tex_pixel;
150
+ // TODO: allow other edge effects, like mirror or wrap
151
+ if (tex_pos.x >= 0 && tex_pos.y >= 0 && tex_pos.x <= 1 && tex_pos.y <= 1) {
152
+ weight = texture2D($kernel, kernel_pos).r;
153
+ // make sure to clamp or we sample outside
154
+ color += texture2D($texture, clamp(tex_pos, 0, 1)) * weight;
155
+ }
156
+ }
157
+ }
158
+
159
+ return color;
160
+ }
161
+ """
162
+
163
+
164
+ class ImageVisual(Visual):
165
+ """Visual subclass displaying an image.
166
+
167
+ Parameters
168
+ ----------
169
+ data : ndarray
170
+ ImageVisual data. Can be shape (M, N), (M, N, 3), or (M, N, 4).
171
+ If floating point data is provided and contains NaNs, they will
172
+ be made transparent (discarded) for the single band data case when
173
+ scaling is done on the GPU (see ``texture_format``). On the CPU,
174
+ single band NaNs are mapped to 0 as they are sent to the GPU which
175
+ result in them using the lowest ``clim`` value in the GPU.
176
+ For RGB data, NaNs will be mapped to the lowest ``clim`` value.
177
+ If the Alpha band is NaN it will be mapped to 0 (transparent).
178
+ Note that NaN handling is not required by some OpenGL implementations
179
+ and NaNs may be treated differently on some systems (ex. as 0s).
180
+ method : str
181
+ Selects method of rendering image in case of non-linear transforms.
182
+ Each method produces similar results, but may trade efficiency
183
+ and accuracy. If the transform is linear, this parameter is ignored
184
+ and a single quad is drawn around the area of the image.
185
+
186
+ * 'auto': Automatically select 'impostor' if the image is drawn
187
+ with a nonlinear transform; otherwise select 'subdivide'.
188
+ * 'subdivide': ImageVisual is represented as a grid of triangles
189
+ with texture coordinates linearly mapped.
190
+ * 'impostor': ImageVisual is represented as a quad covering the
191
+ entire view, with texture coordinates determined by the
192
+ transform. This produces the best transformation results, but may
193
+ be slow.
194
+
195
+ grid: tuple (rows, cols)
196
+ If method='subdivide', this tuple determines the number of rows and
197
+ columns in the image grid.
198
+ cmap : str | ColorMap
199
+ Colormap to use for luminance images.
200
+ clim : str | tuple
201
+ Limits to use for the colormap. I.e. the values that map to black and white
202
+ in a gray colormap. Can be 'auto' to auto-set bounds to
203
+ the min and max of the data. If not given or None, 'auto' is used.
204
+ gamma : float
205
+ Gamma to use during colormap lookup. Final color will be cmap(val**gamma).
206
+ by default: 1.
207
+ interpolation : str
208
+ Selects method of texture interpolation. Makes use of the two hardware
209
+ interpolation methods and the available interpolation methods defined
210
+ in vispy/gloo/glsl/misc/spatial_filters.frag
211
+
212
+ * 'nearest': Default, uses 'nearest' with Texture interpolation.
213
+ * 'linear': uses 'linear' with Texture interpolation.
214
+ * 'hanning', 'hamming', 'hermite', 'kaiser', 'quadric', 'cubic',
215
+ 'catrom', 'mitchell', 'spline16', 'spline36', 'gaussian',
216
+ 'bessel', 'sinc', 'lanczos', 'blackman'
217
+ * 'custom': uses the sampling kernel provided through 'custom_kernel'.
218
+ texture_format: numpy.dtype | str | None
219
+ How to store data on the GPU. OpenGL allows for many different storage
220
+ formats and schemes for the low-level texture data stored in the GPU.
221
+ Most common is unsigned integers or floating point numbers.
222
+ Unsigned integers are the most widely supported while other formats
223
+ may not be supported on older versions of OpenGL or with older GPUs.
224
+ Default value is ``None`` which means data will be scaled on the
225
+ CPU and the result stored in the GPU as an unsigned integer. If a
226
+ numpy dtype object, an internal texture format will be chosen to
227
+ support that dtype and data will *not* be scaled on the CPU. Not all
228
+ dtypes are supported. If a string, then
229
+ it must be one of the OpenGL internalformat strings described in the
230
+ table on this page: https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glTexImage2D.xhtml
231
+ The name should have `GL_` removed and be lowercase (ex.
232
+ `GL_R32F` becomes ``'r32f'``). Lastly, this can also be the string
233
+ ``'auto'`` which will use the data type of the provided image data
234
+ to determine the internalformat of the texture.
235
+ When this is specified (not ``None``) data is scaled on the
236
+ GPU which allows for faster color limit changes. Additionally, when
237
+ 32-bit float data is provided it won't be copied before being
238
+ transferred to the GPU.
239
+ custom_kernel: numpy.ndarray
240
+ Kernel used for texture sampling when interpolation is set to 'custom'.
241
+ **kwargs : dict
242
+ Keyword arguments to pass to `Visual`.
243
+
244
+ Notes
245
+ -----
246
+ The colormap functionality through ``cmap`` and ``clim`` are only used
247
+ if the data are 2D.
248
+ """
249
+
250
+ _shaders = {
251
+ 'vertex': _VERTEX_SHADER,
252
+ 'fragment': _FRAGMENT_SHADER,
253
+ }
254
+
255
+ _func_templates = {
256
+ 'texture_lookup_interpolated': _INTERPOLATION_TEMPLATE,
257
+ 'texture_lookup_custom': _CUSTOM_FILTER,
258
+ 'texture_lookup': _TEXTURE_LOOKUP,
259
+ 'clim_float': _APPLY_CLIM_FLOAT,
260
+ 'clim': _APPLY_CLIM,
261
+ 'gamma_float': _APPLY_GAMMA_FLOAT,
262
+ 'gamma': _APPLY_GAMMA,
263
+ 'null_color_transform': _NULL_COLOR_TRANSFORM,
264
+ 'red_to_luminance': _C2L_RED,
265
+ }
266
+
267
+ def __init__(self, data=None, method='auto', grid=(1, 1),
268
+ cmap='viridis', clim='auto', gamma=1.0,
269
+ interpolation='nearest', texture_format=None,
270
+ custom_kernel=np.ones((1, 1)), **kwargs):
271
+ """Initialize image properties, texture storage, and interpolation methods."""
272
+ self._data = None
273
+
274
+ # load 'float packed rgba8' interpolation kernel
275
+ # to load float interpolation kernel use
276
+ # `load_spatial_filters(packed=False)`
277
+ kernel, interpolation_names = load_spatial_filters()
278
+
279
+ self._kerneltex = Texture2D(kernel, interpolation='nearest')
280
+ # The unpacking can be debugged by changing "spatial-filters.frag"
281
+ # to have the "unpack" function just return the .r component. That
282
+ # combined with using the below as the _kerneltex allows debugging
283
+ # of the pipeline
284
+ # self._kerneltex = Texture2D(kernel, interpolation='linear',
285
+ # internalformat='r32f')
286
+
287
+ interpolation_names, interpolation_fun = self._init_interpolation(
288
+ interpolation_names)
289
+ self._interpolation_names = interpolation_names
290
+ self._interpolation_fun = interpolation_fun
291
+ self._interpolation = interpolation
292
+ if self._interpolation not in self._interpolation_names:
293
+ raise ValueError("interpolation must be one of %s" %
294
+ ', '.join(self._interpolation_names))
295
+
296
+ self._method = method
297
+ self._grid = grid
298
+ self._need_texture_upload = True
299
+ self._need_vertex_update = True
300
+ self._need_colortransform_update = True
301
+ self._need_interpolation_update = True
302
+ self._texture = self._init_texture(data, texture_format)
303
+ self._subdiv_position = VertexBuffer()
304
+ self._subdiv_texcoord = VertexBuffer()
305
+
306
+ # impostor quad covers entire viewport
307
+ vertices = np.array([[-1, -1], [1, -1], [1, 1],
308
+ [-1, -1], [1, 1], [-1, 1]],
309
+ dtype=np.float32)
310
+ self._impostor_coords = VertexBuffer(vertices)
311
+ self._null_tr = NullTransform()
312
+
313
+ self._init_view(self)
314
+
315
+ Visual.__init__(self, vcode=self._shaders['vertex'], fcode=self._shaders['fragment'])
316
+ self.set_gl_state('translucent', cull_face=False)
317
+ self._draw_mode = 'triangles'
318
+
319
+ # define _data_lookup_fn as None, will be setup in
320
+ # self._build_interpolation()
321
+ self._data_lookup_fn = None
322
+
323
+ self.clim = clim or "auto" # None -> "auto"
324
+ self.cmap = cmap
325
+ self.gamma = gamma
326
+ self.custom_kernel = custom_kernel
327
+
328
+ if data is not None:
329
+ self.set_data(data)
330
+ self.freeze()
331
+
332
+ def _init_interpolation(self, interpolation_names):
333
+ # create interpolation shader functions for available interpolations
334
+ fun = [Function(self._func_templates['texture_lookup_interpolated'] % (n + '2D'))
335
+ for n in interpolation_names]
336
+ interpolation_names = [n.lower() for n in interpolation_names]
337
+
338
+ # add custom filter
339
+ fun.append(Function(self._func_templates['texture_lookup_custom']))
340
+ interpolation_names.append('custom')
341
+
342
+ interpolation_fun = dict(zip(interpolation_names, fun))
343
+ interpolation_names = tuple(sorted(interpolation_names))
344
+
345
+ # overwrite "nearest" and "linear" spatial-filters
346
+ # with "hardware" interpolation _data_lookup_fn
347
+ hardware_lookup = Function(self._func_templates['texture_lookup'])
348
+ interpolation_fun['nearest'] = hardware_lookup
349
+ interpolation_fun['linear'] = hardware_lookup
350
+ # alias bilinear to linear and bicubic to cubic (but deprecate)
351
+ interpolation_names = interpolation_names + ('bilinear', 'bicubic')
352
+ return interpolation_names, interpolation_fun
353
+
354
+ def _init_texture(self, data, texture_format, **texture_kwargs):
355
+ if self._interpolation == 'linear':
356
+ texture_interpolation = 'linear'
357
+ else:
358
+ texture_interpolation = 'nearest'
359
+
360
+ if texture_format is None:
361
+ tex = CPUScaledTexture2D(
362
+ data, interpolation=texture_interpolation,
363
+ **texture_kwargs
364
+ )
365
+ else:
366
+ tex = GPUScaledTexture2D(
367
+ data, internalformat=texture_format,
368
+ interpolation=texture_interpolation,
369
+ **texture_kwargs
370
+ )
371
+ return tex
372
+
373
+ def set_data(self, image, copy=False):
374
+ """Set the image data.
375
+
376
+ Parameters
377
+ ----------
378
+ image : array-like
379
+ The image data.
380
+ texture_format : str or None
381
+
382
+ """
383
+ data = np.array(image, copy=copy)
384
+ if np.iscomplexobj(data):
385
+ raise TypeError(
386
+ "Complex data types not supported. Please use 'ComplexImage' instead"
387
+ )
388
+ # can the texture handle this data?
389
+ self._texture.check_data_format(data)
390
+ if self._data is None or self._data.shape[:2] != data.shape[:2]:
391
+ # Only rebuild if the size of the image changed
392
+ self._need_vertex_update = True
393
+ self._data = data
394
+ self._need_texture_upload = True
395
+
396
+ def view(self):
397
+ """Get the :class:`vispy.visuals.visual.VisualView` for this visual."""
398
+ v = Visual.view(self)
399
+ self._init_view(v)
400
+ return v
401
+
402
+ def _init_view(self, view):
403
+ # Store some extra variables per-view
404
+ view._need_method_update = True
405
+ view._method_used = None
406
+
407
+ @property
408
+ def clim(self):
409
+ """Get color limits used when rendering the image (cmin, cmax)."""
410
+ return self._texture.clim
411
+
412
+ @clim.setter
413
+ def clim(self, clim):
414
+ if self._texture.set_clim(clim):
415
+ self._need_texture_upload = True
416
+ self._update_colortransform_clim()
417
+ self.update()
418
+
419
+ def _update_colortransform_clim(self):
420
+ if self._need_colortransform_update:
421
+ # we are going to rebuild anyway so just do it later
422
+ return
423
+ try:
424
+ norm_clims = self._texture.clim_normalized
425
+ except RuntimeError:
426
+ return
427
+ else:
428
+ # shortcut so we don't have to rebuild the whole color transform
429
+ self.shared_program.frag['color_transform'][1]['clim'] = norm_clims
430
+
431
+ @property
432
+ def cmap(self):
433
+ """Get the colormap object applied to luminance (single band) data."""
434
+ return self._cmap
435
+
436
+ @cmap.setter
437
+ def cmap(self, cmap):
438
+ self._cmap = get_colormap(cmap)
439
+ self._need_colortransform_update = True
440
+ self.update()
441
+
442
+ @property
443
+ def gamma(self):
444
+ """Get the gamma used when rendering the image."""
445
+ return self._gamma
446
+
447
+ @gamma.setter
448
+ def gamma(self, value):
449
+ """Set gamma used when rendering the image."""
450
+ if value <= 0:
451
+ raise ValueError("gamma must be > 0")
452
+ self._gamma = float(value)
453
+ # shortcut so we don't have to rebuild the color transform
454
+ if not self._need_colortransform_update:
455
+ self.shared_program.frag['color_transform'][2]['gamma'] = self._gamma
456
+ self.update()
457
+
458
+ @property
459
+ def method(self):
460
+ """Get rendering method name."""
461
+ return self._method
462
+
463
+ @method.setter
464
+ def method(self, m):
465
+ if self._method != m:
466
+ self._method = m
467
+ self._need_vertex_update = True
468
+ self.update()
469
+
470
+ @property
471
+ def size(self):
472
+ """Get size of the image (width, height)."""
473
+ return self._data.shape[:2][::-1]
474
+
475
+ @property
476
+ def interpolation(self):
477
+ """Get interpolation algorithm name."""
478
+ return self._interpolation
479
+
480
+ @interpolation.setter
481
+ def interpolation(self, i):
482
+ if i not in self._interpolation_names:
483
+ raise ValueError("interpolation must be one of %s" %
484
+ ', '.join(self._interpolation_names))
485
+ if self._interpolation != i:
486
+ self._interpolation = i
487
+ self._need_interpolation_update = True
488
+ self.update()
489
+
490
+ @property
491
+ def interpolation_functions(self):
492
+ """Get names of possible interpolation methods."""
493
+ return self._interpolation_names
494
+
495
+ @property
496
+ def custom_kernel(self):
497
+ """Kernel used by 'custom' interpolation for texture sampling"""
498
+ return self._custom_kernel
499
+
500
+ @custom_kernel.setter
501
+ def custom_kernel(self, value):
502
+ value = np.asarray(value, dtype=np.float32)
503
+ if value.ndim != 2:
504
+ raise ValueError(f'kernel must have 2 dimensions; got {value.ndim}')
505
+ self._custom_kernel = value
506
+ self._custom_kerneltex = Texture2D(value, interpolation='nearest', internalformat='r32f')
507
+ if self._data_lookup_fn is not None and 'kernel' in self._data_lookup_fn:
508
+ self._data_lookup_fn['kernel'] = self._custom_kerneltex
509
+ self._data_lookup_fn['kernel_shape'] = value.shape[::-1]
510
+ self.update()
511
+
512
+ # The interpolation code could be transferred to a dedicated filter
513
+ # function in visuals/filters as discussed in #1051
514
+ def _build_interpolation(self):
515
+ """Rebuild the _data_lookup_fn for different interpolations."""
516
+ interpolation = self._interpolation
517
+ # alias bilinear to linear
518
+ if interpolation == 'bilinear':
519
+ warnings.warn(
520
+ "'bilinear' interpolation is Deprecated. Use 'linear' instead.",
521
+ DeprecationWarning,
522
+ stacklevel=2,
523
+ )
524
+ interpolation = 'linear'
525
+ # alias bicubic to cubic
526
+ if interpolation == 'bicubic':
527
+ warnings.warn(
528
+ "'bicubic' interpolation is Deprecated. Use 'cubic' instead.",
529
+ DeprecationWarning,
530
+ stacklevel=2,
531
+ )
532
+ interpolation = 'cubic'
533
+ self._data_lookup_fn = self._interpolation_fun[interpolation]
534
+ self.shared_program.frag['get_data'] = self._data_lookup_fn
535
+
536
+ # only 'linear' and 'custom' use 'linear' texture interpolation
537
+ if interpolation in ('linear', 'custom'):
538
+ texture_interpolation = 'linear'
539
+ else:
540
+ texture_interpolation = 'nearest'
541
+
542
+ # 'nearest' (and also 'linear') doesn't use spatial_filters.frag
543
+ # so u_kernel and shape setting is skipped
544
+ if interpolation not in ('nearest', 'linear'):
545
+ self._data_lookup_fn['shape'] = self._data.shape[:2][::-1]
546
+ if interpolation == 'custom':
547
+ self._data_lookup_fn['kernel'] = self._custom_kerneltex
548
+ self._data_lookup_fn['kernel_shape'] = self._custom_kernel.shape[::-1]
549
+ else:
550
+ self.shared_program['u_kernel'] = self._kerneltex
551
+
552
+ if self._texture.interpolation != texture_interpolation:
553
+ self._texture.interpolation = texture_interpolation
554
+
555
+ self._data_lookup_fn['texture'] = self._texture
556
+
557
+ self._need_interpolation_update = False
558
+
559
+ def _build_vertex_data(self):
560
+ """Rebuild the vertex buffers for the subdivide method."""
561
+ grid = self._grid
562
+ w = 1.0 / grid[1]
563
+ h = 1.0 / grid[0]
564
+
565
+ quad = np.array([[0, 0, 0], [w, 0, 0], [w, h, 0],
566
+ [0, 0, 0], [w, h, 0], [0, h, 0]],
567
+ dtype=np.float32)
568
+ quads = np.empty((grid[1], grid[0], 6, 3), dtype=np.float32)
569
+ quads[:] = quad
570
+
571
+ mgrid = np.mgrid[0.:grid[1], 0.:grid[0]].transpose(1, 2, 0)
572
+ mgrid = mgrid[:, :, np.newaxis, :]
573
+ mgrid[..., 0] *= w
574
+ mgrid[..., 1] *= h
575
+
576
+ quads[..., :2] += mgrid
577
+ tex_coords = quads.reshape(grid[1]*grid[0]*6, 3)
578
+ tex_coords = np.ascontiguousarray(tex_coords[:, :2])
579
+ vertices = tex_coords * self.size
580
+
581
+ self._subdiv_position.set_data(vertices.astype('float32'))
582
+ self._subdiv_texcoord.set_data(tex_coords.astype('float32'))
583
+ self._need_vertex_update = False
584
+
585
+ def _update_method(self, view):
586
+ """Decide which method to use for *view* and configure it accordingly."""
587
+ method = self._method
588
+ if method == 'auto':
589
+ if view.transforms.get_transform().Linear:
590
+ method = 'subdivide'
591
+ else:
592
+ method = 'impostor'
593
+ view._method_used = method
594
+
595
+ if method == 'subdivide':
596
+ view.view_program['method'] = 0
597
+ view.view_program['a_position'] = self._subdiv_position
598
+ view.view_program['a_texcoord'] = self._subdiv_texcoord
599
+ elif method == 'impostor':
600
+ view.view_program['method'] = 1
601
+ view.view_program['a_position'] = self._impostor_coords
602
+ view.view_program['a_texcoord'] = self._impostor_coords
603
+ else:
604
+ raise ValueError("Unknown image draw method '%s'" % method)
605
+
606
+ self.shared_program['image_size'] = self.size
607
+ view._need_method_update = False
608
+ self._prepare_transforms(view)
609
+
610
+ def _build_texture(self):
611
+ try:
612
+ pre_clims = self._texture.clim_normalized
613
+ except RuntimeError:
614
+ pre_clims = "auto"
615
+ pre_internalformat = self._texture.internalformat
616
+ # copy was already made on `set_data` if requested
617
+ self._texture.scale_and_set_data(self._data, copy=False)
618
+ post_clims = self._texture.clim_normalized
619
+ post_internalformat = self._texture.internalformat
620
+ # color transform needs rebuilding if the internalformat was changed
621
+ # new color limits need to be assigned if the normalized clims changed
622
+ # otherwise, the original color transform should be fine
623
+ new_if = post_internalformat != pre_internalformat
624
+ new_cl = post_clims != pre_clims
625
+ if new_if:
626
+ self._need_colortransform_update = True
627
+ elif new_cl and not self._need_colortransform_update:
628
+ # shortcut so we don't have to rebuild the whole color transform
629
+ self.shared_program.frag['color_transform'][1]['clim'] = self._texture.clim_normalized
630
+ self._need_texture_upload = False
631
+
632
+ def _compute_bounds(self, axis, view):
633
+ if axis > 1:
634
+ return 0, 0
635
+ else:
636
+ return 0, self.size[axis]
637
+
638
+ def _build_color_transform(self):
639
+ if self._data.ndim == 2 or self._data.shape[2] == 1:
640
+ # luminance data
641
+ fclim = Function(self._func_templates['clim_float'])
642
+ fgamma = Function(self._func_templates['gamma_float'])
643
+ # NOTE: red_to_luminance only uses the red component, fancy internalformats
644
+ # may need to use the other components or a different function chain
645
+ fun = FunctionChain(
646
+ None, [Function(self._func_templates['red_to_luminance']), fclim, fgamma, Function(self.cmap.glsl_map)]
647
+ )
648
+ else:
649
+ # RGB/A image data (no colormap)
650
+ fclim = Function(self._func_templates['clim'])
651
+ fgamma = Function(self._func_templates['gamma'])
652
+ fun = FunctionChain(None, [Function(self._func_templates['null_color_transform']), fclim, fgamma])
653
+ fclim['clim'] = self._texture.clim_normalized
654
+ fgamma['gamma'] = self.gamma
655
+ return fun
656
+
657
+ def _prepare_transforms(self, view):
658
+ trs = view.transforms
659
+ prg = view.view_program
660
+ method = view._method_used
661
+ if method == 'subdivide':
662
+ prg.vert['transform'] = trs.get_transform()
663
+ prg.frag['transform'] = self._null_tr
664
+ else:
665
+ prg.vert['transform'] = self._null_tr
666
+ prg.frag['transform'] = trs.get_transform().inverse
667
+
668
+ def _prepare_draw(self, view):
669
+ if self._data is None:
670
+ return False
671
+
672
+ if self._need_interpolation_update:
673
+ self._build_interpolation()
674
+
675
+ if self._need_texture_upload:
676
+ self._build_texture()
677
+
678
+ if self._need_colortransform_update:
679
+ prg = view.view_program
680
+ self.shared_program.frag['color_transform'] = self._build_color_transform()
681
+ self._need_colortransform_update = False
682
+ prg['texture2D_LUT'] = self.cmap.texture_lut()
683
+
684
+ if self._need_vertex_update:
685
+ self._build_vertex_data()
686
+
687
+ if view._need_method_update:
688
+ self._update_method(view)