vispy 0.15.0__cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

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

Potentially problematic release.


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

Files changed (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-aarch64-linux-gnu.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,278 @@
1
+ import asyncio
2
+
3
+ from ..base import BaseApplicationBackend, BaseCanvasBackend, BaseTimerBackend
4
+ from ...app import Timer
5
+ from ...util import keys
6
+ from ._offscreen_util import OffscreenContext, FrameBufferHelper
7
+
8
+
9
+ try:
10
+ from jupyter_rfb import RemoteFrameBuffer
11
+ except Exception:
12
+ RemoteFrameBuffer = object
13
+ _msg = 'The jupyter_rfb backend relies on a the jupyter_rfb library: ``pip install jupyter_rfb``'
14
+ available, testable, why_not, which = False, False, _msg, None
15
+ else:
16
+ available, testable, why_not = True, False, None
17
+ which = "jupyter_rfb"
18
+
19
+
20
+ # -------------------------------------------------------------- capability ---
21
+
22
+ capability = dict(
23
+ title=False,
24
+ size=True,
25
+ position=False,
26
+ show=False,
27
+ vsync=False,
28
+ resizable=True,
29
+ decorate=False,
30
+ fullscreen=False,
31
+ context=False, # Could work, but not implemented
32
+ multi_window=True,
33
+ scroll=True,
34
+ parent=False, # ipywidgets has layouts, but has no concept of parents
35
+ always_on_top=False,
36
+ )
37
+
38
+
39
+ # ------------------------------------------------------- set_configuration ---
40
+
41
+ # The configuration mostly applies to the framebuffer. So if we'd want
42
+ # to implement some of that, we'd probably have to apply it to the FBO.
43
+
44
+
45
+ # ------------------------------------------------------------- application ---
46
+
47
+
48
+ class ApplicationBackend(BaseApplicationBackend):
49
+
50
+ def __init__(self):
51
+ super().__init__()
52
+
53
+ def _vispy_get_backend_name(self):
54
+ return 'jupyter_rfb'
55
+
56
+ def _vispy_process_events(self):
57
+ raise RuntimeError("Cannot process events while asyncio event-loop is running.")
58
+
59
+ def _vispy_run(self):
60
+ pass # We're in IPython; don't enter a mainloop or we'll block!
61
+
62
+ def _vispy_quit(self):
63
+ pass
64
+
65
+ def _vispy_get_native_app(self):
66
+ return asyncio
67
+
68
+
69
+ # ------------------------------------------------------------------ canvas ---
70
+
71
+ class CanvasBackend(BaseCanvasBackend, RemoteFrameBuffer):
72
+
73
+ _double_click_supported = True
74
+
75
+ def __init__(self, vispy_canvas, **kwargs):
76
+ BaseCanvasBackend.__init__(self, vispy_canvas)
77
+ RemoteFrameBuffer.__init__(self)
78
+ # Use a context per canvas, because we seem to make assumptions
79
+ # about OpenGL state being local to the canvas.
80
+ self._context = OffscreenContext() # OffscreenContext.get_global_instance()
81
+ self._helper = FrameBufferHelper()
82
+ self._loop = asyncio.get_event_loop()
83
+ self._logical_size = 1, 1
84
+ self._physical_size = 1, 1
85
+ self._lifecycle = 0 # 0: not initialized, 1: initialized, 2: closed
86
+ # Init more based on kwargs (could maybe handle, title, show, context)
87
+ self._vispy_set_size(*kwargs["size"])
88
+ self.resizable = kwargs["resizable"]
89
+ # Need a first update
90
+ self._vispy_update()
91
+
92
+ def handle_event(self, ev):
93
+ type = ev["event_type"]
94
+ if type == "resize":
95
+ # Note that jupyter_rfb already throttles this event
96
+ w, h, r = ev["width"], ev["height"], ev["pixel_ratio"]
97
+ self._logical_size = w, h
98
+ self._physical_size = int(w * r), int(h * r)
99
+ self._helper.set_physical_size(*self._physical_size)
100
+ self._loop.call_soon(self._emit_resize_event)
101
+ self._vispy_update() # make sure to schedule a new draw
102
+ elif type == "pointer_down":
103
+ self._vispy_mouse_press(
104
+ native=ev,
105
+ pos=(ev["x"], ev["y"]),
106
+ button=ev["button"],
107
+ modifiers=self._modifiers(ev),
108
+ )
109
+ elif type == "pointer_up":
110
+ self._vispy_mouse_release(
111
+ native=ev,
112
+ pos=(ev["x"], ev["y"]),
113
+ button=ev["button"],
114
+ modifiers=self._modifiers(ev),
115
+ )
116
+ elif type == "pointer_move":
117
+ self._vispy_mouse_move(
118
+ native=ev,
119
+ pos=(ev["x"], ev["y"]),
120
+ button=ev["button"],
121
+ modifiers=self._modifiers(ev),
122
+ )
123
+ elif type == "double_click":
124
+ self._vispy_mouse_double_click(
125
+ native=ev,
126
+ pos=(ev["x"], ev["y"]),
127
+ button=ev["button"],
128
+ modifiers=self._modifiers(ev),
129
+ )
130
+ elif type == "wheel":
131
+ self._vispy_canvas.events.mouse_wheel(
132
+ native=ev,
133
+ pos=(ev["x"], ev["y"]),
134
+ delta=(ev["dx"] / 100, - ev["dy"] / 100),
135
+ modifiers=self._modifiers(ev),
136
+ )
137
+ elif type == "key_down":
138
+ # The special key names are all (most?) the same
139
+ # But the key is actually more like tex, e.g. shift + 3 becomes "#"
140
+ self._vispy_canvas.events.key_press(
141
+ native=ev,
142
+ key=keys.Key(ev["key"]),
143
+ modifiers=self._modifiers(ev),
144
+ text=ev["key"],
145
+ )
146
+ elif type == "key_up":
147
+ self._vispy_canvas.events.key_release(
148
+ native=ev,
149
+ key=keys.Key(ev["key"]),
150
+ modifiers=self._modifiers(ev),
151
+ text=ev["key"],
152
+ )
153
+ elif type == "close":
154
+ self._lifecycle = 2
155
+ self._context.close()
156
+ _stop_timers(self._vispy_canvas)
157
+ else:
158
+ pass # event ignored / unknown
159
+
160
+ def _modifiers(self, ev):
161
+ return tuple(getattr(keys, m.upper()) for m in ev["modifiers"])
162
+
163
+ def _emit_resize_event(self):
164
+ self._vispy_canvas.events.resize(
165
+ size=self._logical_size,
166
+ physical_size=self._physical_size,
167
+ )
168
+
169
+ def get_frame(self):
170
+ # This gets automatically called by the RFB widget
171
+
172
+ # Only draw if the draw region is not null
173
+ if self._physical_size[0] <= 1 or self._physical_size[1] <= 1:
174
+ return None
175
+
176
+ # Handle initialization
177
+ if not self._lifecycle:
178
+ self._lifecycle = 1
179
+ self._vispy_canvas.set_current()
180
+ self._vispy_canvas.events.initialize()
181
+ self._emit_resize_event()
182
+
183
+ # Draw and obtain result
184
+ self._vispy_canvas.set_current()
185
+ with self._helper:
186
+ self._vispy_canvas.events.draw(region=None)
187
+ array = self._helper.get_frame()
188
+
189
+ # Flush commands here to clean up - otherwise we get errors related to
190
+ # framebuffers not existin.
191
+ self._vispy_canvas.context.flush_commands()
192
+
193
+ return array
194
+
195
+ def _vispy_warmup(self):
196
+ self._vispy_canvas.set_current()
197
+
198
+ def _vispy_set_current(self):
199
+ self._context.make_current()
200
+
201
+ def _vispy_swap_buffers(self):
202
+ pass
203
+
204
+ def _vispy_set_title(self, title):
205
+ pass
206
+
207
+ def _vispy_set_size(self, w, h):
208
+ self.css_width = f"{w}px"
209
+ self.css_height = f"{h}px"
210
+
211
+ def _vispy_set_position(self, x, y):
212
+ pass
213
+
214
+ def _vispy_set_visible(self, visible):
215
+ if not visible:
216
+ raise NotImplementedError("Cannot hide the RFB widget")
217
+
218
+ def _vispy_set_fullscreen(self, fullscreen):
219
+ raise NotImplementedError()
220
+
221
+ def _vispy_update(self):
222
+ self.request_draw()
223
+
224
+ def _vispy_close(self):
225
+ # ipywidget.Widget.close() -> closes the comm and removes all views
226
+ self.close()
227
+
228
+ def _vispy_get_size(self):
229
+ return self._logical_size
230
+
231
+ def _vispy_get_physical_size(self):
232
+ return self._physical_size
233
+
234
+ def _vispy_get_position(self):
235
+ return 0, 0
236
+
237
+ def _vispy_get_fullscreen(self):
238
+ return False
239
+
240
+
241
+ # ------------------------------------------------------------------- timer ---
242
+
243
+ class TimerBackend(BaseTimerBackend):
244
+
245
+ def __init__(self, vispy_timer):
246
+ super().__init__(vispy_timer)
247
+ self._loop = asyncio.get_event_loop()
248
+ self._task = None
249
+
250
+ async def _timer_coro(self, interval):
251
+ while True:
252
+ await asyncio.sleep(interval)
253
+ self._vispy_timeout()
254
+
255
+ def _vispy_start(self, interval):
256
+ if self._task is not None:
257
+ self._task.cancel()
258
+ self._task = asyncio.create_task(self._timer_coro(interval))
259
+
260
+ def _vispy_stop(self):
261
+ self._task.cancel()
262
+ self._task = None
263
+
264
+ def _vispy_timeout(self):
265
+ self._loop.call_soon(self._vispy_timer._timeout)
266
+
267
+
268
+ def _stop_timers(canvas):
269
+ """Stop all timers associated with a canvas."""
270
+ # This is nice and all, but the Canvas object is frozen, so this is never actually used
271
+ for attr in dir(canvas):
272
+ try:
273
+ attr_obj = getattr(canvas, attr)
274
+ except NotImplementedError:
275
+ continue # prevent error due to props that we don't implement
276
+ else:
277
+ if isinstance(attr_obj, Timer):
278
+ attr_obj.stop()
@@ -0,0 +1,121 @@
1
+ """
2
+ Utils for offscreen rendering.
3
+ """
4
+
5
+ from .. import Application, Canvas
6
+ from ... import gloo
7
+
8
+
9
+ class OffscreenContext:
10
+ """ A helper class to provide an OpenGL context. This context is global
11
+ to the application.
12
+ """
13
+
14
+ _global_instance = None
15
+ _canvas = None
16
+
17
+ @classmethod
18
+ def get_global_instance(cls):
19
+ """ Get a global context. Note that any assumptions about OpenGL state
20
+ being local will not hold.
21
+ """
22
+ if cls._global_instance is None:
23
+ cls._global_instance = cls()
24
+ return cls._global_instance
25
+
26
+ def __init__(self):
27
+ if self._canvas is not None:
28
+ return # already initialized
29
+
30
+ self._is_closed = False
31
+
32
+ # Glfw is probably the most lightweight approach, so let's try that.
33
+ # But there are two incompatible packages providing glfw :/
34
+ self.glfw = None
35
+ try:
36
+ import glfw
37
+ except ImportError:
38
+ pass
39
+ else:
40
+ need_from_glfw = ["create_window", "make_context_current"]
41
+ if all(hasattr(glfw, attr) for attr in need_from_glfw):
42
+ self.glfw = glfw
43
+
44
+ if self.glfw:
45
+ self.glfw.init()
46
+ self.glfw.window_hint(self.glfw.VISIBLE, 0)
47
+ self._canvas = self.glfw.create_window(1, 1, "dummy window", None, None)
48
+ else:
49
+ try:
50
+ _app = Application('default')
51
+ except Exception:
52
+ raise RuntimeError(
53
+ "Cannot find a backend to create an OpenGL context. "
54
+ "Install e.g. PyQt5, PySide2, or `pip install glfw`."
55
+ )
56
+ self._canvas = Canvas(app=_app)
57
+ self._canvas.show(False)
58
+
59
+ def make_current(self):
60
+ """ Make this the currently active context.
61
+ """
62
+ # If an application only used off-screen canvases this would technically
63
+ # have to be called just once. But note that an application/session
64
+ # could run both real canvases and off-screen ones.
65
+ if self.glfw:
66
+ self.glfw.make_context_current(self._canvas)
67
+ else:
68
+ self._canvas.set_current()
69
+
70
+ def close(self):
71
+ """ Close the context. """
72
+ # Cannot close the global instance
73
+ if self is OffscreenContext._global_instance:
74
+ return
75
+ elif not self._is_closed:
76
+ self._is_closed = True
77
+ if self.glfw:
78
+ self.glfw.destroy_window(self._canvas)
79
+ else:
80
+ self._canvas.close()
81
+
82
+ def __del__(self):
83
+ self.close()
84
+
85
+
86
+ class FrameBufferHelper:
87
+ """ Provides a canvas to render to, using an FBO.
88
+ """
89
+
90
+ def __init__(self):
91
+ self._fbo = None
92
+ self._physical_size = 1, 1
93
+ self._fbo_size = -1, -1
94
+
95
+ def _ensure_fbo(self):
96
+ if self._fbo_size != self._physical_size:
97
+ self._fbo_size = self._physical_size
98
+ w, h = self._fbo_size
99
+ if self._fbo is None:
100
+ color_buffer = gloo.Texture2D((h, w, 4))
101
+ depth_buffer = gloo.RenderBuffer((h, w))
102
+ self._fbo = gloo.FrameBuffer(color_buffer, depth_buffer)
103
+ else:
104
+ self._fbo.resize((h, w))
105
+
106
+ def set_physical_size(self, w, h):
107
+ """ Set the physical size of the canvas.
108
+ """
109
+ self._physical_size = w, h
110
+
111
+ def get_frame(self):
112
+ """ Call this within the with-context to obtain the frame buffer contents.
113
+ """
114
+ return self._fbo.read()
115
+
116
+ def __enter__(self):
117
+ self._ensure_fbo()
118
+ return self._fbo.__enter__()
119
+
120
+ def __exit__(self, *args):
121
+ return self._fbo.__exit__(*args)
@@ -0,0 +1,235 @@
1
+ # -*- coding: utf-8 -*-
2
+ # vispy: testskip
3
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ """OSMesa backend for offscreen rendering on Linux/Unix."""
6
+ from __future__ import division
7
+ from ...util.ptime import time
8
+ from ..base import (BaseApplicationBackend, BaseCanvasBackend,
9
+ BaseTimerBackend)
10
+ from ...gloo import gl
11
+ from time import sleep
12
+
13
+ try:
14
+ from ...ext import osmesa
15
+ except Exception as exp:
16
+ available, testable, why_not, which = False, False, str(exp), None
17
+ else:
18
+ available, testable, why_not, which = True, True, None, 'OSMesa'
19
+
20
+ # -------------------------------------------------------------- capability ---
21
+ capability = dict(
22
+ # if True they mean:
23
+ title=True, # can set title on the fly
24
+ size=True, # can set size on the fly
25
+ position=False, # can set position on the fly
26
+ show=True, # can show/hide window XXX ?
27
+ vsync=False, # can set window to sync to blank
28
+ resizable=False, # can toggle resizability (e.g., no user resizing)
29
+ decorate=True, # can toggle decorations
30
+ fullscreen=False, # fullscreen window support
31
+ context=True, # can share contexts between windows
32
+ multi_window=True, # can use multiple windows at once
33
+ scroll=False, # scroll-wheel events are supported
34
+ parent=False, # can pass native widget backend parent
35
+ always_on_top=False, # can be made always-on-top
36
+ )
37
+
38
+
39
+ _VP_OSMESA_ALL_WINDOWS = []
40
+
41
+
42
+ def _get_osmesa_windows():
43
+ return [win for win in _VP_OSMESA_ALL_WINDOWS
44
+ if isinstance(win, CanvasBackend)]
45
+
46
+
47
+ # ------------------------------------------------------------- application ---
48
+ class ApplicationBackend(BaseApplicationBackend):
49
+
50
+ def __init__(self):
51
+ BaseApplicationBackend.__init__(self)
52
+ self._timers = list()
53
+
54
+ def _add_timer(self, timer):
55
+ if timer not in self._timers:
56
+ self._timers.append(timer)
57
+
58
+ def _vispy_get_backend_name(self):
59
+ return 'osmesa'
60
+
61
+ def _vispy_process_events(self):
62
+ for timer in self._timers:
63
+ timer._tick()
64
+ wins = _get_osmesa_windows()
65
+ for win in wins:
66
+ if win._needs_draw:
67
+ win._needs_draw = False
68
+ win._on_draw()
69
+
70
+ def _vispy_run(self):
71
+ wins = _get_osmesa_windows()
72
+ while not all(w.closed for w in wins):
73
+ self._vispy_process_events()
74
+ self._vispy_quit()
75
+
76
+ def _vispy_quit(self):
77
+ wins = _get_osmesa_windows()
78
+ for win in wins:
79
+ win._vispy_close()
80
+ for timer in self._timers:
81
+ timer._vispy_stop()
82
+ self._timers = []
83
+
84
+ def _vispy_get_native_app(self):
85
+ return osmesa
86
+
87
+
88
+ class OSMesaContext(object):
89
+ """
90
+ A wrapper around an OSMesa context that destroy the context when
91
+ garbage collected
92
+ """
93
+
94
+ def __init__(self):
95
+ self.context = osmesa.OSMesaCreateContext()
96
+
97
+ def make_current(self, pixels, width, height):
98
+ return osmesa.OSMesaMakeCurrent(self.context, pixels, width, height)
99
+
100
+ def __del__(self):
101
+ osmesa.OSMesaDestroyContext(self.context)
102
+
103
+
104
+ # ------------------------------------------------------------------ canvas ---
105
+ class CanvasBackend(BaseCanvasBackend):
106
+ """OSMesa backend for Canvas"""
107
+
108
+ def __init__(self, vispy_canvas, **kwargs):
109
+ BaseCanvasBackend.__init__(self, vispy_canvas)
110
+ # We use _process_backend_kwargs() to "serialize" the kwargs
111
+ # and to check whether they match this backend's capability
112
+ p = self._process_backend_kwargs(kwargs)
113
+
114
+ # Deal with config
115
+ # TODO: We do not support setting config
116
+ # ... use context.config
117
+ # Deal with context
118
+ p.context.shared.add_ref('osmesa', self)
119
+ if p.context.shared.ref is self:
120
+ self._native_context = OSMesaContext()
121
+ else:
122
+ self._native_context = p.context.shared.ref._native_context
123
+
124
+ self._closed = False
125
+ self._pixels = None
126
+ self._vispy_set_size(*p.size)
127
+ _VP_OSMESA_ALL_WINDOWS.append(self)
128
+
129
+ self._vispy_canvas.set_current()
130
+ self._vispy_canvas.events.initialize()
131
+
132
+ def _vispy_set_current(self):
133
+ if self._native_context is None:
134
+ raise RuntimeError('Native context is None')
135
+ if self._pixels is None:
136
+ raise RuntimeError('Pixel buffer has already been deleted')
137
+
138
+ ok = self._native_context.make_current(self._pixels, self._size[0],
139
+ self._size[1])
140
+ if not ok:
141
+ raise RuntimeError('Failed attaching OSMesa rendering buffer')
142
+
143
+ def _vispy_swap_buffers(self):
144
+ if self._pixels is None:
145
+ raise RuntimeError('No pixel buffer')
146
+ gl.glFinish()
147
+
148
+ def _vispy_set_title(self, title):
149
+ pass
150
+
151
+ def _vispy_set_size(self, w, h):
152
+ self._pixels = osmesa.allocate_pixels_buffer(w, h)
153
+ self._size = (w, h)
154
+ self._vispy_canvas.events.resize(size=(w, h))
155
+ self._vispy_set_current()
156
+ self._vispy_update()
157
+
158
+ def _vispy_set_position(self, x, y):
159
+ pass
160
+
161
+ def _vispy_set_visible(self, visible):
162
+ if visible:
163
+ self._vispy_set_current()
164
+ self._vispy_update()
165
+
166
+ def _vispy_set_fullscreen(self, fullscreen):
167
+ pass
168
+
169
+ def _vispy_update(self):
170
+ # This is checked by osmesa ApplicationBackend in process_events
171
+ self._needs_draw = True
172
+
173
+ def _vispy_close(self):
174
+ if self.closed:
175
+ return
176
+ # We do not set self._native_context = None here because this causes
177
+ # trouble in case a canvas is closed multiple times (as in
178
+ # app.test_run()). The problem occurs in gloo's glir._gl_initialize
179
+ # when it tries to call glGetString(GL_VERSION).
180
+ # But OSMesa requires a context to be attached when calling
181
+ # glGetString otherwise it returns an empty string, which gloo doesn't
182
+ # like
183
+ self._closed = True
184
+ return
185
+
186
+ def _vispy_warmup(self):
187
+ etime = time() + 0.1
188
+ while time() < etime:
189
+ sleep(0.01)
190
+ self._vispy_canvas.set_current()
191
+ self._vispy_canvas.app.process_events()
192
+
193
+ def _vispy_get_size(self):
194
+ if self._pixels is None:
195
+ return
196
+ return self._size
197
+
198
+ @property
199
+ def closed(self):
200
+ return self._closed
201
+
202
+ def _vispy_get_position(self):
203
+ return 0, 0
204
+
205
+ def _vispy_get_fullscreen(self):
206
+ return False
207
+
208
+ def _on_draw(self):
209
+ # This is called by the osmesa ApplicationBackend
210
+ if self._vispy_canvas is None or self._pixels is None:
211
+ raise RuntimeError('draw with no canvas or pixels attached')
212
+ return
213
+ self._vispy_set_current()
214
+ self._vispy_canvas.events.draw(region=None) # (0, 0, w, h)
215
+
216
+
217
+ # ------------------------------------------------------------------- timer ---
218
+ class TimerBackend(BaseTimerBackend):
219
+
220
+ def __init__(self, vispy_timer):
221
+ BaseTimerBackend.__init__(self, vispy_timer)
222
+ vispy_timer._app._backend._add_timer(self)
223
+ self._vispy_stop()
224
+
225
+ def _vispy_start(self, interval):
226
+ self._interval = interval
227
+ self._next_time = time() + self._interval
228
+
229
+ def _vispy_stop(self):
230
+ self._next_time = float('inf')
231
+
232
+ def _tick(self):
233
+ if time() > self._next_time:
234
+ self._vispy_timer._timeout()
235
+ self._next_time = time() + self._interval