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,487 @@
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
+ import warnings
5
+
6
+ import numpy as np
7
+
8
+ from vispy.gloo.texture import Texture2D, Texture3D, convert_dtype_and_clip
9
+ from vispy.util import np_copy_if_needed
10
+
11
+
12
+ def get_default_clim_from_dtype(dtype):
13
+ """Get min and max color limits based on the range of the dtype."""
14
+ # assume floating point data is pre-normalized to 0 and 1
15
+ if np.issubdtype(dtype, np.floating):
16
+ return 0, 1
17
+ # assume integer RGBs fill the whole data space
18
+ dtype_info = np.iinfo(dtype)
19
+ dmin = dtype_info.min
20
+ dmax = dtype_info.max
21
+ return dmin, dmax
22
+
23
+
24
+ def get_default_clim_from_data(data):
25
+ """Compute a reasonable clim from the min and max, taking nans into account.
26
+
27
+ If there are no non-finite values (nan, inf, -inf) this is as fast as it can be.
28
+ Otherwise, this functions is about 3x slower.
29
+ """
30
+ # Fast
31
+ min_value = data.min()
32
+ max_value = data.max()
33
+
34
+ # Need more work? The nan-functions are slower
35
+ min_finite = np.isfinite(min_value)
36
+ max_finite = np.isfinite(max_value)
37
+ if not (min_finite and max_finite):
38
+ finite_data = data[np.isfinite(data)]
39
+ if finite_data.size:
40
+ min_value = finite_data.min()
41
+ max_value = finite_data.max()
42
+ else:
43
+ min_value = max_value = 0 # no finite values in the data
44
+
45
+ return min_value, max_value
46
+
47
+
48
+ class _ScaledTextureMixin:
49
+ """Mixin class to make a texture aware of color limits.
50
+
51
+ This class contains the shared functionality for the CPU and GPU mixin
52
+ classes below. In some cases this class provides a "generic"
53
+ implementation of a specific method and is then overridden by one of the
54
+ subclasses.
55
+
56
+ Parameters
57
+ ----------
58
+ data : ndarray | tuple | None
59
+ Texture data in the form of a numpy array. A tuple of the shape of the
60
+ texture can also be given. However, some subclasses may benefit from
61
+ or even require a numpy array to make decisions based on shape **and**
62
+ dtype.
63
+ **texture_kwargs
64
+ Any other keyword arguments to pass to the parent TextureXD class.
65
+
66
+ """
67
+
68
+ def __init__(self, data=None, **texture_kwargs):
69
+ self._clim = None
70
+ self._data_dtype = None
71
+ data, texture_kwargs = self.init_scaling_texture(data, **texture_kwargs)
72
+ # Call the __init__ of the TextureXD class
73
+ super().__init__(data, **texture_kwargs)
74
+
75
+ def init_scaling_texture(self, data=None, internalformat=None, **texture_kwargs):
76
+ """Initialize scaling properties and create a representative array."""
77
+ self._data_dtype = getattr(data, 'dtype', None)
78
+ data = self._create_rep_array(data)
79
+ internalformat = self._get_texture_format_for_data(
80
+ data,
81
+ internalformat)
82
+ texture_kwargs['internalformat'] = internalformat
83
+ return data, texture_kwargs
84
+
85
+ def _get_texture_format_for_data(self, data, internalformat):
86
+ return internalformat
87
+
88
+ @property
89
+ def clim(self):
90
+ """Color limits of the texture's data."""
91
+ return self._clim
92
+
93
+ def set_clim(self, clim):
94
+ """Set clim and return if a texture update is needed.
95
+
96
+ In this default implementation, it is assumed changing the color limit
97
+ never requires re-uploading the data to the texture (always return
98
+ ``False``).
99
+
100
+ """
101
+ need_texture_upload = False
102
+ if isinstance(clim, str):
103
+ if clim != 'auto':
104
+ raise ValueError('clim must be "auto" if a string')
105
+ self._clim = clim
106
+ else:
107
+ try:
108
+ cmin, cmax = clim
109
+ except (ValueError, TypeError):
110
+ raise ValueError('clim must have two elements')
111
+ self._clim = (cmin, cmax)
112
+ return need_texture_upload
113
+
114
+ @property
115
+ def clim_normalized(self):
116
+ """Normalize current clims to match texture data inside the shader.
117
+
118
+ If data is scaled on the CPU then the texture data will be in the range
119
+ 0-1 in the _build_texture() method. Inside the fragment shader the
120
+ final contrast adjustment will be applied based on this normalized
121
+ ``clim``.
122
+
123
+ """
124
+ if isinstance(self.clim, str) and self.clim == "auto":
125
+ raise RuntimeError("Can't return 'auto' normalized color limits "
126
+ "until data has been set. Call "
127
+ "'scale_and_set_data' first.")
128
+ if self._data_dtype is None:
129
+ raise RuntimeError("Can't return normalized color limits until "
130
+ "data has been set. Call "
131
+ "'scale_and_set_data' first.")
132
+ if self.clim[0] == self.clim[1]:
133
+ return self.clim[0], np.inf
134
+ # if the internalformat of the texture is normalized we need to
135
+ # also normalize the clims so they match in-shader
136
+ clim_min = self.normalize_value(self.clim[0], self._data_dtype)
137
+ clim_max = self.normalize_value(self.clim[1], self._data_dtype)
138
+ return clim_min, clim_max
139
+
140
+ @property
141
+ def is_normalized(self):
142
+ """Whether the in-shader representation of this texture is normalized or not.
143
+
144
+ Formats ending in 'f' (float), 'ui' (unsigned integer), or 'i'
145
+ (signed integer) are not normalized in the GPU. Formats ending in "_snorm"
146
+ are normalized on the range [-1, 1] based on the data type of the
147
+ input data (ex. 0-255 for uint8). Formats with no data type suffix are
148
+ normalized on the range [0, 1]. See
149
+ https://www.khronos.org/opengl/wiki/Image_Format for more information.
150
+
151
+ This property can be used to determine if input shader variables
152
+ (uniforms, template variables) need to also be normalized. See
153
+ :meth:`~BaseTexture.normalize_value` below.
154
+
155
+ """
156
+ if self.internalformat is None:
157
+ return True
158
+ return self.internalformat[-1] not in ('f', 'i')
159
+
160
+ def normalize_value(self, val, input_data_dtype):
161
+ """Normalize values to match in-shader representation of this shader.
162
+
163
+ Parameters
164
+ ----------
165
+ val : int | float | ndarray
166
+ Value(s) to normalize.
167
+ input_data_dtype : numpy.dtype
168
+ Data type of input data. The assumption is that the provided
169
+ values to be normalized are in the same range as the input
170
+ texture data and must be normalized in the same way.
171
+
172
+ """
173
+ if not self.is_normalized:
174
+ return val
175
+ dtype_info = np.iinfo(input_data_dtype)
176
+ dmin = dtype_info.min
177
+ dmax = dtype_info.max
178
+ val = (val - dmin) / (dmax - dmin)
179
+ # XXX: Do we need to handle _snorm differently?
180
+ # Not currently supported in vispy.
181
+ return val
182
+
183
+ def _data_num_channels(self, data):
184
+ # if format == 'luminance':
185
+ # num_channels = 1
186
+ if data is not None:
187
+ # array or shape tuple
188
+ ndim = getattr(data, 'ndim', len(data))
189
+ # Ex. (M, N, 3) in Texture2D (ndim=2) -> 3 channels
190
+ num_channels = data.shape[-1] if ndim == self._ndim + 1 else 1
191
+ else:
192
+ num_channels = 4
193
+ return num_channels
194
+
195
+ def _create_rep_array(self, data):
196
+ """Get a representative array with an initial shape.
197
+
198
+ Data will be filled in and the texture resized later.
199
+
200
+ """
201
+ dtype = getattr(data, 'dtype', np.float32)
202
+ num_channels = self._data_num_channels(data)
203
+ init_shape = (10,) * self._ndim + (num_channels,)
204
+ return np.zeros(init_shape).astype(dtype)
205
+
206
+ def check_data_format(self, data):
207
+ """Check if provided data will cause issues if set later."""
208
+ # this texture type has no limitations
209
+ return
210
+
211
+ def scale_and_set_data(self, data, offset=None, copy=False):
212
+ """Upload new data to the GPU."""
213
+ # we need to call super here or we get infinite recursion
214
+ return super().set_data(data, offset=offset, copy=copy)
215
+
216
+ def set_data(self, data, offset=None, copy=False):
217
+ self.scale_and_set_data(data, offset=offset, copy=copy)
218
+
219
+
220
+ class CPUScaledTextureMixin(_ScaledTextureMixin):
221
+ """Texture mixin class for smarter scaling decisions.
222
+
223
+ This class wraps the logic to normalize data on the CPU before sending
224
+ it to the GPU (the texture). Pre-scaling on the CPU can be helpful in
225
+ cases where OpenGL 2/ES requirements limit the texture storage to an
226
+ 8-bit normalized integer internally.
227
+
228
+ This class includes optimizations where image data is not re-normalized
229
+ if the previous normalization can still be used to visualize the data
230
+ with the new color limits.
231
+
232
+ This class should only be used internally. For similar features where
233
+ scaling occurs on the GPU see
234
+ :class:`vispy.visuals._scalable_textures.GPUScaledTextureMixin`.
235
+
236
+ To use this mixin, a subclass should be created to combine this mixin with
237
+ the texture class being used. Existing subclasses already exist in this
238
+ module. Note that this class **must** appear first in the subclass's parent
239
+ classes so that its ``__init__`` method is called instead of the parent
240
+ Texture class.
241
+
242
+ """
243
+
244
+ def __init__(self, data=None, **texture_kwargs):
245
+ self._data_limits = None
246
+ # Call the __init__ of the mixin base class
247
+ super().__init__(data, **texture_kwargs)
248
+
249
+ def _clim_outside_data_limits(self, cmin, cmax):
250
+ if self._data_limits is None:
251
+ return False
252
+ return cmin < self._data_limits[0] or cmax > self._data_limits[1]
253
+
254
+ def set_clim(self, clim):
255
+ """Set clim and return if a texture update is needed."""
256
+ need_texture_upload = False
257
+ # NOTE: Color limits are not checked against data type limits
258
+ if isinstance(clim, str):
259
+ if clim != 'auto':
260
+ raise ValueError('clim must be "auto" if a string')
261
+ need_texture_upload = True
262
+ self._clim = clim
263
+ else:
264
+ try:
265
+ cmin, cmax = clim
266
+ except (ValueError, TypeError):
267
+ raise ValueError('clim must have two elements')
268
+ if self._clim_outside_data_limits(cmin, cmax):
269
+ need_texture_upload = True
270
+ self._clim = (cmin, cmax)
271
+ return need_texture_upload
272
+
273
+ @property
274
+ def clim_normalized(self):
275
+ """Normalize current clims to match texture data inside the shader.
276
+
277
+ If data is scaled on the CPU then the texture data will be in the range
278
+ 0-1 in the _build_texture() method. Inside the fragment shader the
279
+ final contrast adjustment will be applied based on this normalized
280
+ ``clim``.
281
+
282
+ """
283
+ if isinstance(self.clim, str) and self.clim == "auto":
284
+ raise RuntimeError("Can't return 'auto' normalized color limits "
285
+ "until data has been set. Call "
286
+ "'scale_and_set_data' first.")
287
+ if self._data_limits is None:
288
+ raise RuntimeError("Can't return normalized color limits until "
289
+ "data has been set. Call "
290
+ "'scale_and_set_data' first.")
291
+
292
+ range_min, range_max = self._data_limits
293
+ clim_min, clim_max = self.clim
294
+ full_range = range_max - range_min
295
+ if clim_min == clim_max or full_range == 0:
296
+ return 0, np.inf
297
+ clim_min = (clim_min - range_min) / full_range
298
+ clim_max = (clim_max - range_min) / full_range
299
+ return clim_min, clim_max
300
+
301
+ @staticmethod
302
+ def _scale_data_on_cpu(data, clim, copy=True):
303
+ data = np.array(data, dtype=np.float32, copy=copy or np_copy_if_needed)
304
+ if clim[0] != clim[1]:
305
+ # we always must copy the data if we change it here, otherwise it might change
306
+ # unexpectedly the data held outside of here
307
+ if not copy:
308
+ data = data.copy()
309
+ data -= clim[0]
310
+ data *= 1 / (clim[1] - clim[0])
311
+ return data
312
+
313
+ def scale_and_set_data(self, data, offset=None, copy=True):
314
+ """Upload new data to the GPU, scaling if necessary."""
315
+ if self._data_dtype is None:
316
+ self._data_dtype = data.dtype
317
+
318
+ # ensure dtype is the same as it was before, or funny things happen
319
+ # no copy is performed unless asked for or necessary
320
+ data = convert_dtype_and_clip(data, self._data_dtype, copy=copy)
321
+
322
+ clim = self._clim
323
+ is_auto = isinstance(clim, str) and clim == 'auto'
324
+ if data.ndim == self._ndim or data.shape[self._ndim] == 1:
325
+ if is_auto:
326
+ clim = get_default_clim_from_data(data)
327
+ data = self._scale_data_on_cpu(data, clim, copy=False)
328
+ data_limits = clim
329
+ else:
330
+ data_limits = get_default_clim_from_dtype(data.dtype)
331
+ if is_auto:
332
+ clim = data_limits
333
+
334
+ self._clim = float(clim[0]), float(clim[1])
335
+ self._data_limits = data_limits
336
+ return super().scale_and_set_data(data, offset=offset, copy=False)
337
+
338
+
339
+ class GPUScaledTextureMixin(_ScaledTextureMixin):
340
+ """Texture class for smarter scaling and internalformat decisions.
341
+
342
+ This texture class uses internal formats that are not supported by
343
+ strict OpenGL 2/ES drivers without additional extensions. By using
344
+ this texture we upload data to the GPU in a format as close to
345
+ the original data type as possible (32-bit floats on the CPU are 32-bit
346
+ floats on the GPU). No normalization/scaling happens on the CPU and
347
+ all of it happens on the GPU. This should avoid unnecessary data copies
348
+ as well as provide the highest precision for the final visualization.
349
+
350
+ The texture format may either be a GL enum string (ex. 'r32f'), a numpy
351
+ dtype object (ex. np.float32), or 'auto' which means the texture will
352
+ try to pick the best format for the provided data. By using 'auto' you
353
+ also give the texture permission to change formats in the future if
354
+ new data is provided with a different data type.
355
+
356
+ This class should only be used internally. For similar features where
357
+ scaling occurs on the CPU see
358
+ :class:`vispy.visuals._scalable_textures.CPUScaledTextureMixin`.
359
+
360
+ To use this mixin, a subclass should be created to combine this mixin with
361
+ the texture class being used. Existing subclasses already exist in this
362
+ module. Note that this class **must** appear first in the subclass's parent
363
+ classes so that its ``__init__`` method is called instead of the parent
364
+ Texture class.
365
+
366
+ """
367
+
368
+ # dtype -> internalformat
369
+ # 'r' will be replaced (if needed) with rgb or rgba depending on number of bands
370
+ _texture_dtype_format = {
371
+ np.float32: 'r32f',
372
+ np.float64: 'r32f',
373
+ np.uint8: 'r8', # uint8 normalized
374
+ np.uint16: 'r16', # uint16 normalized
375
+ # np.int8: 'r8', # not supported, there are no signed-integer norm formats
376
+ # np.int16: 'r16',
377
+ # np.uint32: 'r32ui', # not supported, no normal formats for 32bit ints
378
+ # np.int32: 'r32i',
379
+ }
380
+ # instance variable that will be used later on
381
+ _auto_texture_format = False
382
+
383
+ def _handle_auto_texture_format(self, texture_format, data):
384
+ if isinstance(texture_format, str) and texture_format == 'auto':
385
+ if data is None:
386
+ warnings.warn("'texture_format' set to 'auto' but no data "
387
+ "provided. Falling back to CPU scaling.")
388
+ texture_format = None
389
+ else:
390
+ texture_format = data.dtype.type
391
+ self._auto_texture_format = True
392
+ return texture_format
393
+
394
+ def _get_gl_tex_format(self, texture_format, num_channels):
395
+ if texture_format and not isinstance(texture_format, str):
396
+ texture_format = np.dtype(texture_format).type
397
+ if texture_format not in self._texture_dtype_format:
398
+ raise ValueError("Can't determine internal texture format for '{}'".format(texture_format))
399
+ texture_format = self._texture_dtype_format[texture_format]
400
+ # adjust internalformat for format of data (RGBA vs L)
401
+ texture_format = texture_format.replace('r', 'rgba'[:num_channels])
402
+ return texture_format
403
+
404
+ def _get_texture_format_for_data(self, data, internalformat):
405
+ if internalformat is None:
406
+ raise ValueError("'internalformat' must be provided for GPU scaled textures.")
407
+ num_channels = self._data_num_channels(data)
408
+ texture_format = self._handle_auto_texture_format(internalformat, data)
409
+ texture_format = self._get_gl_tex_format(texture_format, num_channels)
410
+ return texture_format
411
+
412
+ def _compute_clim(self, data):
413
+ clim = self._clim
414
+ is_auto = isinstance(clim, str) and clim == 'auto'
415
+ if data.ndim == self._ndim or data.shape[2] == 1:
416
+ if is_auto:
417
+ clim = get_default_clim_from_data(data)
418
+ elif is_auto:
419
+ # assume that RGB data is already scaled (0, 1)
420
+ clim = get_default_clim_from_dtype(data.dtype)
421
+ return float(clim[0]), float(clim[1])
422
+
423
+ def _internalformat_will_change(self, data):
424
+ shape_repr = self._create_rep_array(data)
425
+ new_if = self._get_gl_tex_format(data.dtype, shape_repr.shape[-1])
426
+ return new_if != self.internalformat
427
+
428
+ def check_data_format(self, data):
429
+ """Check if provided data will cause issues if set later."""
430
+ if self._internalformat_will_change(data) and not self._auto_texture_format:
431
+ raise ValueError("Data being set would cause a format change "
432
+ "in the texture. This is only allowed when "
433
+ "'texture_format' is set to 'auto'.")
434
+
435
+ def _reformat_if_necessary(self, data):
436
+ if not self._internalformat_will_change(data):
437
+ return
438
+ if self._auto_texture_format:
439
+ shape_repr = self._create_rep_array(data)
440
+ internalformat = self._get_gl_tex_format(data.dtype, shape_repr.shape[-1])
441
+ self._resize(data.shape, internalformat=internalformat)
442
+ else:
443
+ raise RuntimeError("'internalformat' needs to change but "
444
+ "'texture_format' was not 'auto'.")
445
+
446
+ def scale_and_set_data(self, data, offset=None, copy=False):
447
+ """Upload new data to the GPU, scaling if necessary."""
448
+ self._reformat_if_necessary(data)
449
+ self._data_dtype = np.dtype(data.dtype)
450
+ self._clim = self._compute_clim(data)
451
+ return super().scale_and_set_data(data, offset=offset, copy=copy)
452
+
453
+
454
+ class CPUScaledTexture2D(CPUScaledTextureMixin, Texture2D):
455
+ """Texture class with clim scaling handling builtin.
456
+
457
+ See :class:`vispy.visuals._scalable_textures.CPUScaledTextureMixin` for
458
+ more information.
459
+
460
+ """
461
+
462
+
463
+ class GPUScaledTexture2D(GPUScaledTextureMixin, Texture2D):
464
+ """Texture class with clim scaling handling builtin.
465
+
466
+ See :class:`vispy.visuals._scalable_textures.GPUScaledTextureMixin` for
467
+ more information.
468
+
469
+ """
470
+
471
+
472
+ class CPUScaledTexture3D(CPUScaledTextureMixin, Texture3D):
473
+ """Texture class with clim scaling handling builtin.
474
+
475
+ See :class:`vispy.visuals._scalable_textures.CPUScaledTextureMixin` for
476
+ more information.
477
+
478
+ """
479
+
480
+
481
+ class GPUScaledTextured3D(GPUScaledTextureMixin, Texture3D):
482
+ """Texture class with clim scaling handling builtin.
483
+
484
+ See :class:`vispy.visuals._scalable_textures.GPUScaledTextureMixin` for
485
+ more information.
486
+
487
+ """