vispy 0.15.0__cp312-cp312-macosx_10_13_x86_64.whl

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

Potentially problematic release.


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

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-312-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,923 @@
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
+
6
+ Definitions
7
+ ===========
8
+
9
+ Visual : an object that (1) can be drawn on-screen, (2) can be manipulated
10
+ by configuring the coordinate transformations that it uses.
11
+
12
+ View : a special type of visual that (1) draws the contents of another visual,
13
+ (2) using a different set of transforms. Views have only the basic visual
14
+ interface (draw, bounds, attach, etc.) and lack access to the specific features
15
+ of the visual they are linked to (for example, LineVisual has a ``set_data()``
16
+ method, but there is no corresponding method on a view of a LineVisual).
17
+
18
+
19
+ Class Structure
20
+ ===============
21
+
22
+ * `BaseVisual` - provides transforms and view creation
23
+ This class lays out the basic API for all visuals: ``draw()``, ``bounds()``,
24
+ ``view()``, and ``attach()`` methods, as well as a `TransformSystem` instance
25
+ that determines where the visual will be drawn.
26
+ * `Visual` - defines a shader program to draw.
27
+ Subclasses are responsible for supplying the shader code and configuring
28
+ program variables, including transforms.
29
+ * `VisualView` - clones the shader program from a Visual instance.
30
+ Instances of `VisualView` contain their own shader program,
31
+ transforms and filter attachments, and generally behave like a normal
32
+ instance of `Visual`.
33
+ * `CompoundVisual` - wraps multiple Visual instances.
34
+ These visuals provide no program of their own, but instead rely on one or
35
+ more internally generated `Visual` instances to do their drawing. For
36
+ example, a PolygonVisual consists of an internal LineVisual and
37
+ MeshVisual.
38
+ * `CompoundVisualView` - wraps multiple VisualView instances.
39
+ This allows a `CompoundVisual` to be viewed with a different set of
40
+ transforms and filters.
41
+
42
+
43
+ Making Visual Subclasses
44
+ ========================
45
+
46
+ When making subclasses of `Visual`, it is only necessary to reimplement the
47
+ ``_prepare_draw()``, ``_prepare_transforms()``, and ``_compute_bounds()``
48
+ methods. These methods will be called by the visual automatically when it is
49
+ needed for itself or for a view of the visual.
50
+
51
+ It is important to remember
52
+ when implementing these methods that most changes made to the visual's shader
53
+ program should also be made to the programs for each view. To make this easier,
54
+ the visual uses a `MultiProgram`, which allows all shader programs across the
55
+ visual and its views to be accessed simultaneously. For example::
56
+
57
+ def _prepare_draw(self, view):
58
+ # This line applies to the visual and all of its views
59
+ self.shared_program['a_position'] = self._vbo
60
+
61
+ # This line applies only to the view that is about to be drawn
62
+ view.view_program['u_color'] = (1, 1, 1, 1)
63
+
64
+ Under most circumstances, it is not necessary to reimplement `VisualView`
65
+ because a view will directly access the ``_prepare`` and ``_compute`` methods
66
+ from the visual it is viewing. However, if the `Visual` to be viewed is a
67
+ subclass that reimplements other methods such as ``draw()`` or ``bounds()``,
68
+ then it will be necessary to provide a new matching `VisualView` subclass.
69
+
70
+
71
+ Making CompoundVisual Subclasses
72
+ ================================
73
+
74
+ Compound visual subclasses are generally very easy to construct::
75
+
76
+ class PlotLineVisual(visuals.CompoundVisual):
77
+ def __init__(self, ...):
78
+ self._line = LineVisual(...)
79
+ self._point = PointVisual(...)
80
+ visuals.CompoundVisual.__init__(self, [self._line, self._point])
81
+
82
+ A compound visual will automatically handle forwarding transform system changes
83
+ and filter attachments to its internally-wrapped visuals. To the user, this
84
+ will appear to behave as a single visual.
85
+ """
86
+ from __future__ import division
87
+ import weakref
88
+ from contextlib import contextmanager
89
+
90
+ import numpy as np
91
+
92
+ from .. import gloo
93
+ from ..util.event import EmitterGroup, Event
94
+ from ..util import logger, Frozen
95
+ from .shaders import StatementList, MultiProgram
96
+ from .transforms import TransformSystem
97
+
98
+
99
+ class VisualShare(object):
100
+ """Contains data that is shared between all views of a visual.
101
+
102
+ This includes:
103
+
104
+ * GL state variables (blending, depth test, etc.)
105
+ * A weak dictionary of all views
106
+ * A list of filters that should be applied to all views
107
+ * A cache for bounds.
108
+
109
+ """
110
+
111
+ def __init__(self):
112
+ # Note: in some cases we will need to compute bounds independently for
113
+ # each view. That will have to be worked out later..
114
+ self.bounds = {}
115
+ self.gl_state = {}
116
+ self.views = weakref.WeakKeyDictionary()
117
+ self.filters = []
118
+ self.visible = True
119
+
120
+
121
+ class BaseVisual(Frozen):
122
+ """Superclass for all visuals.
123
+
124
+ This class provides:
125
+
126
+ * A TransformSystem.
127
+ * Two events: `update` and `bounds_change`.
128
+ * Minimal framework for creating views of the visual.
129
+ * A data structure that is shared between all views of the visual.
130
+ * Abstract `draw`, `bounds`, `attach`, and `detach` methods.
131
+
132
+ Parameters
133
+ ----------
134
+ vshare : instance of VisualShare | None
135
+ The visual share.
136
+
137
+ Notes
138
+ -----
139
+ When used in the scenegraph, all Visual classes are mixed with
140
+ `vispy.scene.Node` in order to implement the methods, attributes and
141
+ capabilities required for their usage within it.
142
+
143
+ This subclasses Frozen so that subclasses can easily freeze their
144
+ properties.
145
+ """
146
+
147
+ def __init__(self, vshare=None):
148
+ self._view_class = getattr(self, '_view_class', VisualView)
149
+
150
+ self._vshare = VisualShare() if vshare is None else vshare
151
+ self._vshare.views[self] = None
152
+
153
+ self.events = EmitterGroup(source=self,
154
+ auto_connect=True,
155
+ update=Event,
156
+ bounds_change=Event
157
+ )
158
+
159
+ self._transforms = None
160
+ self.transforms = TransformSystem()
161
+
162
+ @property
163
+ def transform(self):
164
+ return self.transforms.visual_transform.transforms[0]
165
+
166
+ @transform.setter
167
+ def transform(self, tr):
168
+ self.transforms.visual_transform = tr
169
+
170
+ @property
171
+ def transforms(self):
172
+ return self._transforms
173
+
174
+ @transforms.setter
175
+ def transforms(self, trs):
176
+ if trs is self._transforms:
177
+ return
178
+ if self._transforms is not None:
179
+ self._transforms.changed.disconnect(self._transform_changed)
180
+ self._transforms = trs
181
+ trs.changed.connect(self._transform_changed)
182
+ self._transform_changed()
183
+
184
+ def get_transform(self, map_from='visual', map_to='render'):
185
+ """Return a transform mapping between any two coordinate systems.
186
+
187
+ Parameters
188
+ ----------
189
+ map_from : str
190
+ The starting coordinate system to map from. Must be one of: visual,
191
+ scene, document, canvas, framebuffer, or render.
192
+ map_to : str
193
+ The ending coordinate system to map to. Must be one of: visual,
194
+ scene, document, canvas, framebuffer, or render.
195
+ """
196
+ return self.transforms.get_transform(map_from, map_to)
197
+
198
+ @property
199
+ def visible(self):
200
+ return self._vshare.visible
201
+
202
+ @visible.setter
203
+ def visible(self, v):
204
+ if v != self._vshare.visible:
205
+ self._vshare.visible = v
206
+ self.update()
207
+
208
+ def view(self):
209
+ """Return a new view of this visual."""
210
+ return self._view_class(self)
211
+
212
+ def draw(self):
213
+ raise NotImplementedError(self)
214
+
215
+ def attach(self, filt, view=None):
216
+ """Attach a Filter to this visual.
217
+
218
+ Each filter modifies the appearance or behavior of the visual.
219
+
220
+ Parameters
221
+ ----------
222
+ filt : object
223
+ The filter to attach.
224
+ view : instance of VisualView | None
225
+ The view to use.
226
+ """
227
+ raise NotImplementedError(self)
228
+
229
+ def detach(self, filt, view=None):
230
+ """Detach a filter.
231
+
232
+ Parameters
233
+ ----------
234
+ filt : object
235
+ The filter to detach.
236
+ view : instance of VisualView | None
237
+ The view to use.
238
+ """
239
+ raise NotImplementedError(self)
240
+
241
+ def bounds(self, axis, view=None):
242
+ """Get the bounds of the Visual
243
+
244
+ Parameters
245
+ ----------
246
+ axis : int
247
+ The axis.
248
+ view : instance of VisualView
249
+ The view to use.
250
+ """
251
+ if view is None:
252
+ view = self
253
+ if axis not in self._vshare.bounds:
254
+ self._vshare.bounds[axis] = self._compute_bounds(axis, view)
255
+ return self._vshare.bounds[axis]
256
+
257
+ def _compute_bounds(self, axis, view):
258
+ raise NotImplementedError(self)
259
+
260
+ def _bounds_changed(self):
261
+ self._vshare.bounds.clear()
262
+
263
+ def update(self):
264
+ """Update the Visual"""
265
+ self.events.update()
266
+
267
+ def _transform_changed(self, event=None):
268
+ self.update()
269
+
270
+
271
+ class BaseVisualView(object):
272
+ """Base class for a view on a visual.
273
+
274
+ This class must be mixed with another Visual class to work properly. It
275
+ works mainly by forwarding the calls to _prepare_draw, _prepare_transforms,
276
+ and _compute_bounds to the viewed visual.
277
+ """
278
+
279
+ def __init__(self, visual):
280
+ self._visual = visual
281
+
282
+ @property
283
+ def visual(self):
284
+ return self._visual
285
+
286
+ def _prepare_draw(self, view=None):
287
+ self._visual._prepare_draw(view=view)
288
+
289
+ def _prepare_transforms(self, view):
290
+ self._visual._prepare_transforms(view)
291
+
292
+ def _compute_bounds(self, axis, view):
293
+ self._visual._compute_bounds(axis, view)
294
+
295
+ def __repr__(self):
296
+ return '<%s on %r>' % (self.__class__.__name__, self._visual)
297
+
298
+
299
+ class Visual(BaseVisual):
300
+ """Base class for all visuals that can be drawn using a single shader
301
+ program.
302
+
303
+ This class creates a MultiProgram, which is an object that
304
+ behaves like a normal shader program (you can assign shader code, upload
305
+ values, set template variables, etc.) but internally manages multiple
306
+ ModularProgram instances, one per view.
307
+
308
+ Subclasses generally only need to reimplement _compute_bounds,
309
+ _prepare_draw, and _prepare_transforms.
310
+
311
+ Parameters
312
+ ----------
313
+ vcode : str
314
+ Vertex shader code.
315
+ fcode : str
316
+ Fragment shader code.
317
+ gcode : str or None
318
+ Optional geometry shader code.
319
+ program : instance of Program | None
320
+ The program to use. If None, a program will be constructed using
321
+ ``vcode`` and ``fcode``.
322
+ vshare : instance of VisualShare | None
323
+ The visual share, if necessary.
324
+ """
325
+
326
+ def __init__(self, vcode='', fcode='', gcode=None, program=None,
327
+ vshare=None):
328
+ self._view_class = VisualView
329
+ BaseVisual.__init__(self, vshare)
330
+ if vshare is None:
331
+ self._vshare.draw_mode = None
332
+ self._vshare.index_buffer = None
333
+ if program is None:
334
+ self._vshare.program = MultiProgram(vcode, fcode, gcode)
335
+ else:
336
+ self._vshare.program = program
337
+ if len(vcode) > 0 or len(fcode) > 0:
338
+ raise ValueError("Cannot specify both program and "
339
+ "vcode/fcode arguments.")
340
+
341
+ self._prev_gl_state = []
342
+ self._program = self._vshare.program.add_program()
343
+ self._prepare_transforms(self)
344
+ self._filters = []
345
+ self._hooks = {}
346
+
347
+ def set_gl_state(self, preset=None, **kwargs):
348
+ """Define the set of GL state parameters to use when drawing.
349
+
350
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
351
+
352
+ This can also be used as a context manager that will revert the
353
+ gl_state on exit. When used as a context manager, this function is
354
+ designed to be constructed directly in the header of the `with`
355
+ statement to avoid confusion about what state will be restored on exit.
356
+
357
+ Parameters
358
+ ----------
359
+ preset : str
360
+ Preset to use.
361
+ **kwargs : dict
362
+ Keyword arguments.
363
+ """
364
+ prev_gl_state = self._vshare.gl_state.copy()
365
+
366
+ self._vshare.gl_state = kwargs
367
+ self._vshare.gl_state['preset'] = preset
368
+
369
+ return _revert_gl_state([(self, prev_gl_state)])
370
+
371
+ def update_gl_state(self, *args, **kwargs):
372
+ """Modify the set of GL state parameters to use when drawing.
373
+
374
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
375
+
376
+ This can also be used as a context manager that will revert the
377
+ gl_state on exit.
378
+
379
+ Parameters
380
+ ----------
381
+ *args : tuple
382
+ Arguments.
383
+ **kwargs : dict
384
+ Keyword arguments.
385
+ """
386
+ prev_gl_state = self._vshare.gl_state.copy()
387
+
388
+ if len(args) == 1:
389
+ self._vshare.gl_state['preset'] = args[0]
390
+ elif len(args) != 0:
391
+ raise TypeError("Only one positional argument allowed.")
392
+ self._vshare.gl_state.update(kwargs)
393
+
394
+ return _revert_gl_state([(self, prev_gl_state)])
395
+
396
+ def push_gl_state(self, *args, **kwargs):
397
+ """Define the set of GL state parameters to use when drawing.
398
+
399
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
400
+
401
+ This differs from :py:meth:`.set_gl_state` in that it stashes the
402
+ current state. See :py:meth:`.pop_gl_state` for restoring the state.
403
+
404
+ Parameters
405
+ ----------
406
+ *args : tuple
407
+ Arguments.
408
+ **kwargs : dict
409
+ Keyword arguments.
410
+ """
411
+ self._prev_gl_state.append(self._vshare.gl_state.copy())
412
+ self.set_gl_state(*args, **kwargs)
413
+
414
+ def push_gl_state_update(self, *args, **kwargs):
415
+ """Modify the set of GL state parameters to use when drawing.
416
+
417
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
418
+
419
+ This differs from :py:meth:`.update_gl_state` in that it stashes the
420
+ current state. See :py:meth:`.pop_gl_state` for restoring the state.
421
+
422
+ Parameters
423
+ ----------
424
+ *args : tuple
425
+ Arguments.
426
+ **kwargs : dict
427
+ Keyword arguments.
428
+ """
429
+ self._prev_gl_state.append(self._vshare.gl_state.copy())
430
+ self.update_gl_state(*args, **kwargs)
431
+
432
+ def pop_gl_state(self):
433
+ """Restore a previous set of GL state parameters if available.
434
+
435
+ If no previous GL state is available (see :py:meth:`.push_gl_state`),
436
+ this has no effect.
437
+ """
438
+ if self._prev_gl_state:
439
+ self.set_gl_state(**self._prev_gl_state.pop())
440
+
441
+ def _compute_bounds(self, axis, view):
442
+ """Return the (min, max) bounding values of this visual along *axis*
443
+ in the local coordinate system.
444
+ """
445
+ return None
446
+
447
+ def _prepare_draw(self, view=None):
448
+ """This visual is about to be drawn.
449
+
450
+ Visuals should implement this method to ensure that all program
451
+ and GL state variables are updated immediately before drawing.
452
+
453
+ Return False to indicate that the visual should not be drawn.
454
+ """
455
+ return True
456
+
457
+ def _prepare_transforms(self, view):
458
+ """This method is called whenever the TransformSystem instance is
459
+ changed for a view.
460
+
461
+ Assign a view's transforms to the proper shader template variables
462
+ on the view's shader program.
463
+
464
+ Note that each view has its own TransformSystem. In this method we
465
+ connect the appropriate mapping functions from the view's
466
+ TransformSystem to the view's program.
467
+ """
468
+ raise NotImplementedError()
469
+ # Todo: this method can be removed if we somehow enable the shader
470
+ # to specify exactly which transform functions it needs by name. For
471
+ # example:
472
+ #
473
+ # // mapping function is automatically defined from the
474
+ # // corresponding transform in the view's TransformSystem
475
+ # gl_Position = visual_to_render(a_position);
476
+ #
477
+
478
+ @property
479
+ def shared_program(self):
480
+ return self._vshare.program
481
+
482
+ @property
483
+ def view_program(self):
484
+ return self._program
485
+
486
+ @property
487
+ def _draw_mode(self):
488
+ return self._vshare.draw_mode
489
+
490
+ @_draw_mode.setter
491
+ def _draw_mode(self, m):
492
+ self._vshare.draw_mode = m
493
+
494
+ @property
495
+ def _index_buffer(self):
496
+ return self._vshare.index_buffer
497
+
498
+ @_index_buffer.setter
499
+ def _index_buffer(self, buf):
500
+ self._vshare.index_buffer = buf
501
+
502
+ def draw(self):
503
+ if not self.visible:
504
+ return
505
+ if self._prepare_draw(view=self) is False:
506
+ return
507
+
508
+ if self._vshare.draw_mode is None:
509
+ raise ValueError("_draw_mode has not been set for visual %r" %
510
+ self)
511
+
512
+ self._configure_gl_state()
513
+ try:
514
+ self._program.draw(self._vshare.draw_mode,
515
+ self._vshare.index_buffer)
516
+ except Exception:
517
+ logger.warning("Error drawing visual %r" % self)
518
+ raise
519
+
520
+ def _configure_gl_state(self):
521
+ gloo.set_state(**self._vshare.gl_state)
522
+
523
+ def _get_hook(self, shader, name):
524
+ """Return a FunctionChain that Filters may use to modify the program.
525
+
526
+ *shader* should be "vert", "geom", or "frag"
527
+ *name* should be "pre" or "post"
528
+ """
529
+ assert name in ('pre', 'post')
530
+ key = (shader, name)
531
+ if key in self._hooks:
532
+ return self._hooks[key]
533
+ hook = StatementList()
534
+ if shader == 'vert':
535
+ self.view_program.vert[name] = hook
536
+ elif shader == 'frag':
537
+ self.view_program.frag[name] = hook
538
+ elif shader == 'geom':
539
+ self.view_program.geom[name] = hook
540
+ else:
541
+ raise ValueError("shader must be vert, geom, or frag")
542
+ self._hooks[key] = hook
543
+ return hook
544
+
545
+ def attach(self, filt, view=None):
546
+ """Attach a Filter to this visual
547
+
548
+ Each filter modifies the appearance or behavior of the visual.
549
+
550
+ Parameters
551
+ ----------
552
+ filt : object
553
+ The filter to attach.
554
+ view : instance of VisualView | None
555
+ The view to use.
556
+ """
557
+ if view is None:
558
+ self._vshare.filters.append(filt)
559
+ for view in self._vshare.views.keys():
560
+ filt._attach(view)
561
+ else:
562
+ view._filters.append(filt)
563
+ filt._attach(view)
564
+
565
+ def detach(self, filt, view=None):
566
+ """Detach a filter.
567
+
568
+ Parameters
569
+ ----------
570
+ filt : object
571
+ The filter to detach.
572
+ view : instance of VisualView | None
573
+ The view to use.
574
+ """
575
+ if view is None:
576
+ self._vshare.filters.remove(filt)
577
+ for view in self._vshare.views.keys():
578
+ filt._detach(view)
579
+ else:
580
+ view._filters.remove(filt)
581
+ filt._detach(view)
582
+
583
+
584
+ class VisualView(BaseVisualView, Visual):
585
+ """A view on another Visual instance.
586
+
587
+ View instances are created by calling ``visual.view()``.
588
+
589
+ Because this is a subclass of `Visual`, all instances of `VisualView`
590
+ define their own shader program (which is a clone of the viewed visual's
591
+ program), transforms, and filter attachments.
592
+ """
593
+
594
+ def __init__(self, visual):
595
+ BaseVisualView.__init__(self, visual)
596
+ Visual.__init__(self, vshare=visual._vshare)
597
+
598
+ # Attach any shared filters
599
+ for filt in self._vshare.filters:
600
+ filt._attach(self)
601
+
602
+
603
+ class CompoundVisual(BaseVisual):
604
+ """Visual consisting entirely of sub-visuals.
605
+
606
+ To the user, a compound visual behaves exactly like a normal visual--it
607
+ has a transform system, draw() and bounds() methods, etc. Internally, the
608
+ compound visual automatically manages proxying these transforms and methods
609
+ to its sub-visuals.
610
+
611
+ Parameters
612
+ ----------
613
+ subvisuals : list of BaseVisual instances
614
+ The list of visuals to be combined in this compound visual.
615
+ """
616
+
617
+ def __init__(self, subvisuals):
618
+ self._view_class = CompoundVisualView
619
+ self._subvisuals = []
620
+ BaseVisual.__init__(self)
621
+ for v in subvisuals:
622
+ self.add_subvisual(v)
623
+ self.freeze()
624
+
625
+ def add_subvisual(self, visual):
626
+ """Add a subvisual
627
+
628
+ Parameters
629
+ ----------
630
+ visual : instance of Visual
631
+ The visual to add.
632
+ """
633
+ visual.transforms = self.transforms
634
+ visual._prepare_transforms(visual)
635
+ self._subvisuals.append(visual)
636
+ visual.events.update.connect(self._subv_update)
637
+ self.update()
638
+
639
+ def remove_subvisual(self, visual):
640
+ """Remove a subvisual
641
+
642
+ Parameters
643
+ ----------
644
+ visual : instance of Visual
645
+ The visual to remove.
646
+ """
647
+ visual.events.update.disconnect(self._subv_update)
648
+ self._subvisuals.remove(visual)
649
+ self.update()
650
+
651
+ def _subv_update(self, event):
652
+ self.update()
653
+
654
+ def _transform_changed(self, event=None):
655
+ for v in self._subvisuals:
656
+ v.transforms = self.transforms
657
+ BaseVisual._transform_changed(self)
658
+
659
+ def draw(self):
660
+ """Draw the visual"""
661
+ if not self.visible:
662
+ return
663
+ if self._prepare_draw(view=self) is False:
664
+ return
665
+
666
+ for v in self._subvisuals:
667
+ if v.visible:
668
+ v.draw()
669
+
670
+ def _prepare_draw(self, view):
671
+ pass
672
+
673
+ def _prepare_transforms(self, view):
674
+ for v in view._subvisuals:
675
+ v._prepare_transforms(v)
676
+
677
+ def set_gl_state(self, preset=None, **kwargs):
678
+ """Define the set of GL state parameters to use when drawing.
679
+
680
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
681
+
682
+ This can also be used as a context manager that will revert the
683
+ gl_state on exit.
684
+
685
+ Parameters
686
+ ----------
687
+ preset : str
688
+ Preset to use.
689
+ **kwargs : dict
690
+ Keyword arguments.
691
+ """
692
+ prev_gl_state = []
693
+ for v in self._subvisuals:
694
+ prev_gl_state.append((v, v._vshare.gl_state))
695
+ v.set_gl_state(preset=preset, **kwargs)
696
+
697
+ return _revert_gl_state(prev_gl_state)
698
+
699
+ def update_gl_state(self, *args, **kwargs):
700
+ """Modify the set of GL state parameters to use when drawing.
701
+
702
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
703
+
704
+ This can also be used as a context manager that will revert the
705
+ gl_state on exit.
706
+
707
+ Parameters
708
+ ----------
709
+ *args : tuple
710
+ Arguments.
711
+ **kwargs : dict
712
+ Keyword arguments.
713
+ """
714
+ prev_gl_state = []
715
+ for v in self._subvisuals:
716
+ prev_gl_state.append((v, v._vshare.gl_state))
717
+ v.update_gl_state(*args, **kwargs)
718
+
719
+ return _revert_gl_state(prev_gl_state)
720
+
721
+ def push_gl_state(self, *args, **kwargs):
722
+ """Define the set of GL state parameters to use when drawing.
723
+
724
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
725
+
726
+ This differs from :py:meth:`.set_gl_state` in that it stashes the
727
+ current state. See :py:meth:`.pop_gl_state` for restoring the state.
728
+
729
+ Parameters
730
+ ----------
731
+ *args : tuple
732
+ Arguments.
733
+ **kwargs : dict
734
+ Keyword arguments.
735
+ """
736
+ for v in self._subvisuals:
737
+ v.push_gl_state(*args, **kwargs)
738
+
739
+ def push_gl_state_update(self, *args, **kwargs):
740
+ """Modify the set of GL state parameters to use when drawing.
741
+
742
+ The arguments are forwarded to :func:`vispy.gloo.wrappers.set_state`.
743
+
744
+ This differs from :py:meth:`.update_gl_state` in that it stashes the
745
+ current state. See :py:meth:`.pop_gl_state` for restoring the state.
746
+
747
+ Parameters
748
+ ----------
749
+ *args : tuple
750
+ Arguments.
751
+ **kwargs : dict
752
+ Keyword arguments.
753
+ """
754
+ for v in self._subvisuals:
755
+ v.push_gl_state_update(*args, **kwargs)
756
+
757
+ def pop_gl_state(self):
758
+ """Restore a previous set of GL state parameters if available.
759
+
760
+ If no previous GL state is available (see :py:meth:`.push_gl_state`),
761
+ this has no effect.
762
+ """
763
+ for v in self._subvisuals:
764
+ v.pop_gl_state()
765
+
766
+ def attach(self, filt, view=None):
767
+ """Attach a Filter to this visual
768
+
769
+ Each filter modifies the appearance or behavior of the visual.
770
+
771
+ Parameters
772
+ ----------
773
+ filt : object
774
+ The filter to attach.
775
+ view : instance of VisualView | None
776
+ The view to use.
777
+ """
778
+ for v in self._subvisuals:
779
+ v.attach(filt, v)
780
+
781
+ def detach(self, filt, view=None):
782
+ """Detach a filter.
783
+
784
+ Parameters
785
+ ----------
786
+ filt : object
787
+ The filter to detach.
788
+ view : instance of VisualView | None
789
+ The view to use.
790
+ """
791
+ for v in self._subvisuals:
792
+ v.detach(filt, v)
793
+
794
+ def _compute_bounds(self, axis, view):
795
+ bounds = None
796
+ for v in view._subvisuals:
797
+ if v.visible:
798
+ vb = v.bounds(axis)
799
+ if bounds is None:
800
+ bounds = vb
801
+ elif vb is not None:
802
+ bounds = [min(bounds[0], vb[0]), max(bounds[1], vb[1])]
803
+ return bounds
804
+
805
+
806
+ @contextmanager
807
+ def _revert_gl_state(prev_gl_state):
808
+ """Context manager to store and revert GL state for a list of visuals.
809
+
810
+ Parameters
811
+ ----------
812
+ prev_gl_state : list
813
+ A list of (Visual, gl_state) tuples, where gl_state is a dictionary of
814
+ `gl_state` params as would be passed to :py:func:`set_gl_state`.
815
+ """
816
+ for v, state in prev_gl_state:
817
+ v._prev_gl_state.append(state)
818
+ try:
819
+ yield
820
+ finally:
821
+ for v, _ in prev_gl_state:
822
+ v.pop_gl_state()
823
+
824
+
825
+ class CompoundVisualView(BaseVisualView, CompoundVisual):
826
+ def __init__(self, visual):
827
+ BaseVisualView.__init__(self, visual)
828
+ # Create a view on each sub-visual
829
+ subv = [v.view() for v in visual._subvisuals]
830
+ CompoundVisual.__init__(self, subv)
831
+
832
+ # Attach any shared filters
833
+ for filt in self._vshare.filters:
834
+ for v in self._subvisuals:
835
+ filt._attach(v)
836
+
837
+
838
+ class updating_property:
839
+ """A property descriptor that autoupdates the Visual during attribute setting.
840
+
841
+ Use this as a decorator in place of the @property when you want the attribute to trigger
842
+ an immediate update to the visual upon change. You may additionally declare an @setter,
843
+ and if you do, it will be called in addition to the standard logic:
844
+ `self._attr_name = value`.
845
+
846
+ For example, the following code examples are equivalent::
847
+
848
+ class SomeVisual1(Visual):
849
+ def __init__(self, someprop=None):
850
+ self._someprop = someprop
851
+
852
+ @property
853
+ def someprop(self):
854
+ return self._someprop
855
+
856
+ @someprop.setter
857
+ def someprop(self, value):
858
+ previous = self._someprop
859
+ if (previous is None) or np.any(value != previous):
860
+ self._someprop = value
861
+ self._need_update = True
862
+ if hasattr(self, 'events'):
863
+ self.update()
864
+
865
+ class SomeVisual2(Visual):
866
+ def __init__(self, someprop=None):
867
+ self._someprop = someprop
868
+
869
+ @updating_property
870
+ def someprop(self):
871
+ pass
872
+
873
+ NOTE: by default the __get__ method here will look for the conventional `_attr_name`
874
+ property on the object. The result of this is that you don't actually have to put
875
+ anything in the body of a method decorated with @updating_property if you don't want to
876
+ do anything other than retrieve the property. So you may see this slightly strange
877
+ pattern being used::
878
+
879
+ class SomeVisual2(Visual):
880
+ def __init__(self, someprop=None):
881
+ self._someprop = someprop
882
+
883
+ @updating_property
884
+ def someprop(self):
885
+ '''the docstring (or pass) is all that is needed'''
886
+
887
+ """
888
+
889
+ def __init__(self, fget=None, fset=None, doc=None):
890
+ self.fget = fget
891
+ self.fset = fset
892
+ if self.fget is not None:
893
+ self.attr_name = f'_{self.fget.__name__}'
894
+ self.__doc__ = doc or self.fget.__doc__
895
+
896
+ def __get__(self, obj, objtype=None):
897
+ if obj is None:
898
+ return self
899
+ # if the @updating_property getter returns a value, use that
900
+ val = self.fget(obj)
901
+ if val is not None:
902
+ return val
903
+ # otherwise get the private attribute by the same name
904
+ return getattr(obj, self.attr_name, None)
905
+
906
+ def __set__(self, obj, value):
907
+ previous = getattr(obj, self.attr_name, None)
908
+ if (previous is None) or np.any(value != previous):
909
+ setattr(obj, self.attr_name, value)
910
+ # if a @.setter method has been declared, run that as well
911
+ # (overriding the standard setter behavior)
912
+ if self.fset is not None:
913
+ self.fset(obj, value)
914
+ obj._need_update = True
915
+ # prevent update during obj.__init__
916
+ if hasattr(obj, 'events'):
917
+ obj.update()
918
+
919
+ def __delete__(self, obj):
920
+ raise AttributeError("can't delete attribute")
921
+
922
+ def setter(self, fset):
923
+ return type(self)(self.fget, fset, self.__doc__)