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,447 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from __future__ import division # just to be safe...
6
+
7
+ import numpy as np
8
+ from copy import deepcopy
9
+
10
+ from ..util import logger
11
+ from ._color_dict import _color_dict
12
+ from .color_space import (_hex_to_rgba, _rgb_to_hex, _rgb_to_hsv, # noqa
13
+ _hsv_to_rgb, _rgb_to_lab, _lab_to_rgb) # noqa
14
+
15
+
16
+ ###############################################################################
17
+ # User-friendliness helpers
18
+
19
+ def _string_to_rgb(color):
20
+ """Convert user string or hex color to color array (length 3 or 4)"""
21
+ if not color.startswith('#'):
22
+ if color.lower() not in _color_dict:
23
+ raise ValueError('Color "%s" unknown' % color)
24
+ color = _color_dict[color.lower()]
25
+ assert color[0] == '#'
26
+ # hex color
27
+ color = color[1:]
28
+ lc = len(color)
29
+ if lc in (3, 4):
30
+ color = ''.join(c + c for c in color)
31
+ lc = len(color)
32
+ if lc not in (6, 8):
33
+ raise ValueError('Hex color must have exactly six or eight '
34
+ 'elements following the # sign')
35
+ color = np.array([int(color[i:i+2], 16) / 255. for i in range(0, lc, 2)])
36
+ return color
37
+
38
+
39
+ def _user_to_rgba(color, expand=True, clip=False):
40
+ """Convert color(s) from any set of fmts (str/hex/arr) to RGB(A) array"""
41
+ if color is None:
42
+ color = np.zeros(4, np.float32)
43
+ if isinstance(color, str):
44
+ color = _string_to_rgb(color)
45
+ elif isinstance(color, ColorArray):
46
+ color = color.rgba
47
+ # We have to treat this specially
48
+ elif isinstance(color, (list, tuple)):
49
+ if any(isinstance(c, (str, ColorArray)) for c in color):
50
+ color = [_user_to_rgba(c, expand=expand, clip=clip) for c in color]
51
+ if any(len(c) > 1 for c in color):
52
+ raise RuntimeError('could not parse colors, are they nested?')
53
+ color = [c[0] for c in color]
54
+ color = np.atleast_2d(color).astype(np.float32)
55
+ if color.shape[1] not in (3, 4):
56
+ raise ValueError('color must have three or four elements')
57
+ if expand and color.shape[1] == 3: # only expand if requested
58
+ color = np.concatenate((color, np.ones((color.shape[0], 1))),
59
+ axis=1)
60
+ if color.min() < 0 or color.max() > 1:
61
+ if clip:
62
+ color = np.clip(color, 0, 1)
63
+ else:
64
+ raise ValueError("Color values must be between 0 and 1 (or use "
65
+ "clip=True to automatically clip the values).")
66
+ return color
67
+
68
+
69
+ def _array_clip_val(val):
70
+ """Helper to turn val into array and clip between 0 and 1"""
71
+ val = np.array(val)
72
+ if val.max() > 1 or val.min() < 0:
73
+ logger.warning('value will be clipped between 0 and 1')
74
+ val[...] = np.clip(val, 0, 1)
75
+ return val
76
+
77
+
78
+ ###############################################################################
79
+ # Color Array
80
+
81
+
82
+ class ColorArray(object):
83
+ """An array of colors
84
+
85
+ Parameters
86
+ ----------
87
+ color : str | tuple | list of colors
88
+ If str, can be any of the names in ``vispy.color.get_color_names``.
89
+ Can also be a hex value if it starts with ``'#'`` as ``'#ff0000'``.
90
+ If array-like, it must be an Nx3 or Nx4 array-like object.
91
+ Can also be a list of colors, such as
92
+ ``['red', '#00ff00', ColorArray('blue')]``.
93
+ alpha : float | None
94
+ If no alpha is not supplied in ``color`` entry and ``alpha`` is None,
95
+ then this will default to 1.0 (opaque). If float, it will override
96
+ any alpha values in ``color``, if provided.
97
+ clip : bool
98
+ Clip the color value.
99
+ color_space : 'rgb' | 'hsv'
100
+ 'rgb' (default) : color tuples are interpreted as (r, g, b) components.
101
+ 'hsv' : color tuples are interpreted as (h, s, v) components.
102
+
103
+ Examples
104
+ --------
105
+ There are many ways to define colors. Here are some basic cases:
106
+
107
+ >>> from vispy.color import ColorArray
108
+ >>> r = ColorArray('red') # using string name
109
+ >>> r
110
+ <ColorArray: 1 color ((1.0, 0.0, 0.0, 1.0))>
111
+ >>> g = ColorArray((0, 1, 0, 1)) # RGBA tuple
112
+ >>> b = ColorArray('#0000ff') # hex color
113
+ >>> w = ColorArray() # defaults to black
114
+ >>> w.rgb = r.rgb + g.rgb + b.rgb
115
+ >>>hsv_color = ColorArray(color_space="hsv", color=(0, 0, 0.5))
116
+ >>>hsv_color
117
+ <ColorArray: 1 color ((0.5, 0.5, 0.5, 1.0))>
118
+ >>> w == ColorArray('white')
119
+ True
120
+ >>> w.alpha = 0
121
+ >>> w
122
+ <ColorArray: 1 color ((1.0, 1.0, 1.0, 0.0))>
123
+ >>> rgb = ColorArray(['r', (0, 1, 0), '#0000FFFF'])
124
+ >>> rgb
125
+ <ColorArray: 3 colors ((1.0, 0.0, 0.0, 1.0) ... (1.0, 0.0, 0.0, 1.0))>
126
+ >>> rgb == ColorArray(['red', '#00ff00', ColorArray('blue')])
127
+ True
128
+
129
+ Notes
130
+ -----
131
+ Under the hood, this class stores data in RGBA format suitable for use
132
+ on the GPU.
133
+ """
134
+
135
+ def __init__(self, color=(0., 0., 0.), alpha=None,
136
+ clip=False, color_space='rgb'):
137
+
138
+ # if color is RGB, then set the default color to black
139
+ color = (0,) * 4 if color is None else color
140
+ if color_space == 'hsv':
141
+ # if the color space is hsv, convert hsv to rgb
142
+ color = _hsv_to_rgb(color)
143
+ elif color_space != 'rgb':
144
+ raise ValueError('color_space should be either "rgb" or'
145
+ '"hsv", it is ' + color_space)
146
+
147
+ # Parse input type, and set attribute"""
148
+ rgba = _user_to_rgba(color, clip=clip)
149
+
150
+ if alpha is not None:
151
+ rgba[:, 3] = alpha
152
+ self._rgba = None
153
+ self.rgba = rgba
154
+
155
+ ###########################################################################
156
+ # Builtins and utilities
157
+ def copy(self):
158
+ """Return a copy"""
159
+ return deepcopy(self)
160
+
161
+ @classmethod
162
+ def _name(cls):
163
+ """Helper to get the class name once it's been created"""
164
+ return cls.__name__
165
+
166
+ def __array__(self, dtype=None):
167
+ """Get a standard numpy array representing RGBA."""
168
+ rgba = self.rgba
169
+ if dtype is not None:
170
+ rgba = rgba.astype(dtype)
171
+ return rgba
172
+
173
+ def __len__(self):
174
+ return self._rgba.shape[0]
175
+
176
+ def __repr__(self):
177
+ nice_str = str(tuple(self._rgba[0]))
178
+ plural = ''
179
+ if len(self) > 1:
180
+ plural = 's'
181
+ nice_str += ' ... ' + str(tuple(self.rgba[-1]))
182
+ # use self._name() here instead of hard-coding name in case
183
+ # we eventually subclass this class
184
+ return ('<%s: %i color%s (%s)>' % (self._name(), len(self),
185
+ plural, nice_str))
186
+
187
+ def __eq__(self, other):
188
+ return np.array_equal(self._rgba, other._rgba)
189
+
190
+ ###########################################################################
191
+ def __getitem__(self, item):
192
+ if isinstance(item, tuple):
193
+ raise ValueError('ColorArray indexing is only allowed along '
194
+ 'the first dimension.')
195
+ subrgba = self._rgba[item]
196
+ if subrgba.ndim == 1:
197
+ assert len(subrgba) == 4
198
+ elif subrgba.ndim == 2:
199
+ assert subrgba.shape[1] in (3, 4)
200
+ return ColorArray(subrgba)
201
+
202
+ def __setitem__(self, item, value):
203
+ if isinstance(item, tuple):
204
+ raise ValueError('ColorArray indexing is only allowed along '
205
+ 'the first dimension.')
206
+ # value should be a RGBA array, or a ColorArray instance
207
+ if isinstance(value, ColorArray):
208
+ value = value.rgba
209
+ self._rgba[item] = value
210
+
211
+ def extend(self, colors):
212
+ """Extend a ColorArray with new colors
213
+
214
+ Parameters
215
+ ----------
216
+ colors : instance of ColorArray
217
+ The new colors.
218
+ """
219
+ colors = ColorArray(colors)
220
+ self._rgba = np.vstack((self._rgba, colors._rgba))
221
+ return self
222
+
223
+ # RGB(A)
224
+ @property
225
+ def rgba(self):
226
+ """Nx4 array of RGBA floats"""
227
+ return self._rgba.copy()
228
+
229
+ @rgba.setter
230
+ def rgba(self, val):
231
+ """Set the color using an Nx4 array of RGBA floats"""
232
+ # Note: all other attribute sets get routed here!
233
+ # This method is meant to do the heavy lifting of setting data
234
+ rgba = _user_to_rgba(val, expand=False)
235
+ if self._rgba is None:
236
+ self._rgba = rgba # only on init
237
+ else:
238
+ self._rgba[:, :rgba.shape[1]] = rgba
239
+
240
+ @property
241
+ def rgb(self):
242
+ """Nx3 array of RGB floats"""
243
+ return self._rgba[:, :3].copy()
244
+
245
+ @rgb.setter
246
+ def rgb(self, val):
247
+ """Set the color using an Nx3 array of RGB floats"""
248
+ self.rgba = val
249
+
250
+ @property
251
+ def RGBA(self):
252
+ """Nx4 array of RGBA uint8s"""
253
+ return (self._rgba * 255).astype(np.uint8)
254
+
255
+ @RGBA.setter
256
+ def RGBA(self, val):
257
+ """Set the color using an Nx4 array of RGBA uint8 values"""
258
+ # need to convert to normalized float
259
+ val = np.atleast_1d(val).astype(np.float32) / 255
260
+ self.rgba = val
261
+
262
+ @property
263
+ def RGB(self):
264
+ """Nx3 array of RGBA uint8s"""
265
+ return np.round(self._rgba[:, :3] * 255).astype(int)
266
+
267
+ @RGB.setter
268
+ def RGB(self, val):
269
+ """Set the color using an Nx3 array of RGB uint8 values"""
270
+ # need to convert to normalized float
271
+ val = np.atleast_1d(val).astype(np.float32) / 255.
272
+ self.rgba = val
273
+
274
+ @property
275
+ def alpha(self):
276
+ """Length-N array of alpha floats"""
277
+ return self._rgba[:, 3]
278
+
279
+ @alpha.setter
280
+ def alpha(self, val):
281
+ """Set the color using alpha"""
282
+ self._rgba[:, 3] = _array_clip_val(val)
283
+
284
+ ###########################################################################
285
+ # HEX
286
+ @property
287
+ def hex(self):
288
+ """Numpy array with N elements, each one a hex triplet string"""
289
+ return _rgb_to_hex(self._rgba)
290
+
291
+ @hex.setter
292
+ def hex(self, val):
293
+ """Set the color values using a list of hex strings"""
294
+ self.rgba = _hex_to_rgba(val)
295
+
296
+ ###########################################################################
297
+ # HSV
298
+ @property
299
+ def hsv(self):
300
+ """Nx3 array of HSV floats"""
301
+ return self._hsv
302
+
303
+ @hsv.setter
304
+ def hsv(self, val):
305
+ """Set the color values using an Nx3 array of HSV floats"""
306
+ self.rgba = _hsv_to_rgb(val)
307
+
308
+ @property
309
+ def _hsv(self):
310
+ """Nx3 array of HSV floats"""
311
+ # this is done privately so that overriding functions work
312
+ return _rgb_to_hsv(self._rgba[:, :3])
313
+
314
+ @property
315
+ def value(self):
316
+ """Length-N array of color HSV values"""
317
+ return self._hsv[:, 2]
318
+
319
+ @value.setter
320
+ def value(self, val):
321
+ """Set the color using length-N array of (from HSV)"""
322
+ hsv = self._hsv
323
+ hsv[:, 2] = _array_clip_val(val)
324
+ self.rgba = _hsv_to_rgb(hsv)
325
+
326
+ def lighter(self, dv=0.1, copy=True):
327
+ """Produce a lighter color (if possible)
328
+
329
+ Parameters
330
+ ----------
331
+ dv : float
332
+ Amount to increase the color value by.
333
+ copy : bool
334
+ If False, operation will be carried out in-place.
335
+
336
+ Returns
337
+ -------
338
+ color : instance of ColorArray
339
+ The lightened Color.
340
+ """
341
+ color = self.copy() if copy else self
342
+ color.value += dv
343
+ return color
344
+
345
+ def darker(self, dv=0.1, copy=True):
346
+ """Produce a darker color (if possible)
347
+
348
+ Parameters
349
+ ----------
350
+ dv : float
351
+ Amount to decrease the color value by.
352
+ copy : bool
353
+ If False, operation will be carried out in-place.
354
+
355
+ Returns
356
+ -------
357
+ color : instance of ColorArray
358
+ The darkened Color.
359
+ """
360
+ color = self.copy() if copy else self
361
+ color.value -= dv
362
+ return color
363
+
364
+ ###########################################################################
365
+ # Lab
366
+ @property
367
+ def lab(self):
368
+ return _rgb_to_lab(self._rgba[:, :3])
369
+
370
+ @lab.setter
371
+ def lab(self, val):
372
+ self.rgba = _lab_to_rgb(val)
373
+
374
+
375
+ class Color(ColorArray):
376
+ """A single color
377
+
378
+ Parameters
379
+ ----------
380
+ color : str | tuple
381
+ If str, can be any of the names in ``vispy.color.get_color_names``.
382
+ Can also be a hex value if it starts with ``'#'`` as ``'#ff0000'``.
383
+ If array-like, it must be an 1-dimensional array with 3 or 4 elements.
384
+ alpha : float | None
385
+ If no alpha is not supplied in ``color`` entry and ``alpha`` is None,
386
+ then this will default to 1.0 (opaque). If float, it will override
387
+ the alpha value in ``color``, if provided.
388
+ clip : bool
389
+ If True, clip the color values.
390
+ """
391
+
392
+ def __init__(self, color='black', alpha=None, clip=False):
393
+ """Parse input type, and set attribute"""
394
+ if isinstance(color, (list, tuple)):
395
+ color = np.array(color, np.float32)
396
+ rgba = _user_to_rgba(color, clip=clip)
397
+ if rgba.shape[0] != 1:
398
+ raise ValueError('color must be of correct shape')
399
+ if alpha is not None:
400
+ rgba[:, 3] = alpha
401
+ self._rgba = None
402
+ self.rgba = rgba.ravel()
403
+
404
+ @ColorArray.rgba.getter
405
+ def rgba(self):
406
+ return super(Color, self).rgba[0]
407
+
408
+ @ColorArray.rgb.getter
409
+ def rgb(self):
410
+ return super(Color, self).rgb[0]
411
+
412
+ @ColorArray.RGBA.getter
413
+ def RGBA(self):
414
+ return super(Color, self).RGBA[0]
415
+
416
+ @ColorArray.RGB.getter
417
+ def RGB(self):
418
+ return super(Color, self).RGB[0]
419
+
420
+ @ColorArray.alpha.getter
421
+ def alpha(self):
422
+ return super(Color, self).alpha[0]
423
+
424
+ @ColorArray.hex.getter
425
+ def hex(self):
426
+ return super(Color, self).hex[0]
427
+
428
+ @ColorArray.hsv.getter
429
+ def hsv(self):
430
+ return super(Color, self).hsv[0]
431
+
432
+ @ColorArray.value.getter
433
+ def value(self):
434
+ return super(Color, self).value[0]
435
+
436
+ @ColorArray.lab.getter
437
+ def lab(self):
438
+ return super(Color, self).lab[0]
439
+
440
+ @property
441
+ def is_blank(self):
442
+ """Boolean indicating whether the color is invisible."""
443
+ return self.rgba[3] == 0
444
+
445
+ def __repr__(self):
446
+ nice_str = str(tuple(self._rgba[0]))
447
+ return ('<%s: %s>' % (self._name(), nice_str))
@@ -0,0 +1,181 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from __future__ import division # just to be safe...
6
+
7
+ import numpy as np
8
+
9
+
10
+ ###############################################################################
11
+ # Utility functions
12
+ def _check_color_dim(val):
13
+ """Ensure val is Nx(n_col), usually Nx3"""
14
+ val = np.atleast_2d(val)
15
+ if val.shape[1] not in (3, 4):
16
+ raise RuntimeError('Value must have second dimension of size 3 or 4')
17
+ return val, val.shape[1]
18
+
19
+
20
+ ###############################################################################
21
+ # RGB<->HEX conversion
22
+
23
+ def _hex_to_rgba(hexs):
24
+ """Convert hex to rgba, permitting alpha values in hex"""
25
+ hexs = np.atleast_1d(np.array(hexs, '|U9'))
26
+ out = np.ones((len(hexs), 4), np.float32)
27
+ for hi, h in enumerate(hexs):
28
+ assert isinstance(h, str)
29
+ off = 1 if h[0] == '#' else 0
30
+ assert len(h) in (6+off, 8+off)
31
+ e = (len(h)-off) // 2
32
+ out[hi, :e] = [int(h[i:i+2], 16) / 255.
33
+ for i in range(off, len(h), 2)]
34
+ return out
35
+
36
+
37
+ def _rgb_to_hex(rgbs):
38
+ """Convert rgb to hex triplet"""
39
+ rgbs, n_dim = _check_color_dim(rgbs)
40
+ return np.array(['#%02x%02x%02x' % tuple((255*rgb[:3]).astype(np.uint8))
41
+ for rgb in rgbs], '|U7')
42
+
43
+
44
+ ###############################################################################
45
+ # RGB<->HSV conversion
46
+
47
+ def _rgb_to_hsv(rgbs):
48
+ """Convert Nx3 or Nx4 rgb to hsv"""
49
+ rgbs, n_dim = _check_color_dim(rgbs)
50
+ hsvs = list()
51
+ for rgb in rgbs:
52
+ rgb = rgb[:3] # don't use alpha here
53
+ idx = np.argmax(rgb)
54
+ val = rgb[idx]
55
+ c = val - np.min(rgb)
56
+ if c == 0:
57
+ hue = 0
58
+ sat = 0
59
+ else:
60
+ if idx == 0: # R == max
61
+ hue = ((rgb[1] - rgb[2]) / c) % 6
62
+ elif idx == 1: # G == max
63
+ hue = (rgb[2] - rgb[0]) / c + 2
64
+ else: # B == max
65
+ hue = (rgb[0] - rgb[1]) / c + 4
66
+ hue *= 60
67
+ sat = c / val
68
+ hsv = [hue, sat, val]
69
+ hsvs.append(hsv)
70
+ hsvs = np.array(hsvs, dtype=np.float32)
71
+ if n_dim == 4:
72
+ hsvs = np.concatenate((hsvs, rgbs[:, 3]), axis=1)
73
+ return hsvs
74
+
75
+
76
+ def _hsv_to_rgb(hsvs):
77
+ """Convert Nx3 or Nx4 hsv to rgb"""
78
+ hsvs, n_dim = _check_color_dim(hsvs)
79
+ # In principle, we *might* be able to vectorize this, but might as well
80
+ # wait until a compelling use case appears
81
+ rgbs = list()
82
+ for hsv in hsvs:
83
+ c = hsv[1] * hsv[2]
84
+ m = hsv[2] - c
85
+ hp = hsv[0] / 60
86
+ x = c * (1 - abs(hp % 2 - 1))
87
+ if 0 <= hp < 1:
88
+ r, g, b = c, x, 0
89
+ elif hp < 2:
90
+ r, g, b = x, c, 0
91
+ elif hp < 3:
92
+ r, g, b = 0, c, x
93
+ elif hp < 4:
94
+ r, g, b = 0, x, c
95
+ elif hp < 5:
96
+ r, g, b = x, 0, c
97
+ else:
98
+ r, g, b = c, 0, x
99
+ rgb = [r + m, g + m, b + m]
100
+ rgbs.append(rgb)
101
+ rgbs = np.array(rgbs, dtype=np.float32)
102
+ if n_dim == 4:
103
+ rgbs = np.concatenate((rgbs, hsvs[:, 3]), axis=1)
104
+ return rgbs
105
+
106
+
107
+ ###############################################################################
108
+ # RGB<->CIELab conversion
109
+
110
+ # These numbers are adapted from MIT-licensed MATLAB code for
111
+ # Lab<->RGB conversion. They provide an XYZ<->RGB conversion matrices,
112
+ # w/D65 white point normalization built in.
113
+
114
+ # _rgb2xyz = np.array([[0.412453, 0.357580, 0.180423],
115
+ # [0.212671, 0.715160, 0.072169],
116
+ # [0.019334, 0.119193, 0.950227]])
117
+ # _white_norm = np.array([0.950456, 1.0, 1.088754])
118
+ # _rgb2xyz /= _white_norm[:, np.newaxis]
119
+ # _rgb2xyz_norm = _rgb2xyz.T
120
+ _rgb2xyz_norm = np.array([[0.43395276, 0.212671, 0.01775791],
121
+ [0.37621941, 0.71516, 0.10947652],
122
+ [0.18982783, 0.072169, 0.87276557]])
123
+
124
+ # _xyz2rgb = np.array([[3.240479, -1.537150, -0.498535],
125
+ # [-0.969256, 1.875992, 0.041556],
126
+ # [0.055648, -0.204043, 1.057311]])
127
+ # _white_norm = np.array([0.950456, 1., 1.088754])
128
+ # _xyz2rgb *= _white_norm[np.newaxis, :]
129
+ _xyz2rgb_norm = np.array([[3.07993271, -1.53715, -0.54278198],
130
+ [-0.92123518, 1.875992, 0.04524426],
131
+ [0.05289098, -0.204043, 1.15115158]])
132
+
133
+
134
+ def _rgb_to_lab(rgbs):
135
+ rgbs, n_dim = _check_color_dim(rgbs)
136
+ # convert RGB->XYZ
137
+ xyz = rgbs[:, :3].copy() # a misnomer for now but will end up being XYZ
138
+ over = xyz > 0.04045
139
+ xyz[over] = ((xyz[over] + 0.055) / 1.055) ** 2.4
140
+ xyz[~over] /= 12.92
141
+ xyz = np.dot(xyz, _rgb2xyz_norm)
142
+ over = xyz > 0.008856
143
+ xyz[over] = xyz[over] ** (1. / 3.)
144
+ xyz[~over] = 7.787 * xyz[~over] + 0.13793103448275862
145
+
146
+ # Convert XYZ->LAB
147
+ L = (116. * xyz[:, 1]) - 16
148
+ a = 500 * (xyz[:, 0] - xyz[:, 1])
149
+ b = 200 * (xyz[:, 1] - xyz[:, 2])
150
+ labs = [L, a, b]
151
+ # Append alpha if necessary
152
+ if n_dim == 4:
153
+ labs.append(np.atleast1d(rgbs[:, 3]))
154
+ labs = np.array(labs, order='F').T # Becomes 'C' order b/c of .T
155
+ return labs
156
+
157
+
158
+ def _lab_to_rgb(labs):
159
+ """Convert Nx3 or Nx4 lab to rgb"""
160
+ # adapted from BSD-licensed work in MATLAB by Mark Ruzon
161
+ # Based on ITU-R Recommendation BT.709 using the D65
162
+ labs, n_dim = _check_color_dim(labs)
163
+
164
+ # Convert Lab->XYZ (silly indexing used to preserve dimensionality)
165
+ y = (labs[:, 0] + 16.) / 116.
166
+ x = (labs[:, 1] / 500.) + y
167
+ z = y - (labs[:, 2] / 200.)
168
+ xyz = np.concatenate(([x], [y], [z])) # 3xN
169
+ over = xyz > 0.2068966
170
+ xyz[over] = xyz[over] ** 3.
171
+ xyz[~over] = (xyz[~over] - 0.13793103448275862) / 7.787
172
+
173
+ # Convert XYZ->LAB
174
+ rgbs = np.dot(_xyz2rgb_norm, xyz).T
175
+ over = rgbs > 0.0031308
176
+ rgbs[over] = 1.055 * (rgbs[over] ** (1. / 2.4)) - 0.055
177
+ rgbs[~over] *= 12.92
178
+ if n_dim == 4:
179
+ rgbs = np.concatenate((rgbs, labs[:, 3]), axis=1)
180
+ rgbs = np.clip(rgbs, 0., 1.)
181
+ return rgbs