vispy 0.14.0__cp311-cp311-macosx_11_0_arm64.whl

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

Potentially problematic release.


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

Files changed (519) hide show
  1. vispy/__init__.py +33 -0
  2. vispy/app/__init__.py +15 -0
  3. vispy/app/_default_app.py +76 -0
  4. vispy/app/_detect_eventloop.py +148 -0
  5. vispy/app/application.py +263 -0
  6. vispy/app/backends/__init__.py +52 -0
  7. vispy/app/backends/_egl.py +264 -0
  8. vispy/app/backends/_glfw.py +513 -0
  9. vispy/app/backends/_jupyter_rfb.py +278 -0
  10. vispy/app/backends/_offscreen_util.py +121 -0
  11. vispy/app/backends/_osmesa.py +235 -0
  12. vispy/app/backends/_pyglet.py +451 -0
  13. vispy/app/backends/_pyqt4.py +36 -0
  14. vispy/app/backends/_pyqt5.py +36 -0
  15. vispy/app/backends/_pyqt6.py +40 -0
  16. vispy/app/backends/_pyside.py +37 -0
  17. vispy/app/backends/_pyside2.py +52 -0
  18. vispy/app/backends/_pyside6.py +53 -0
  19. vispy/app/backends/_qt.py +968 -0
  20. vispy/app/backends/_sdl2.py +444 -0
  21. vispy/app/backends/_template.py +244 -0
  22. vispy/app/backends/_test.py +8 -0
  23. vispy/app/backends/_tk.py +800 -0
  24. vispy/app/backends/_wx.py +476 -0
  25. vispy/app/backends/tests/__init__.py +0 -0
  26. vispy/app/backends/tests/test_offscreen_util.py +52 -0
  27. vispy/app/backends/tests/test_rfb.py +77 -0
  28. vispy/app/base.py +294 -0
  29. vispy/app/canvas.py +828 -0
  30. vispy/app/qt.py +92 -0
  31. vispy/app/tests/__init__.py +0 -0
  32. vispy/app/tests/qt-designer.ui +58 -0
  33. vispy/app/tests/test_app.py +442 -0
  34. vispy/app/tests/test_backends.py +164 -0
  35. vispy/app/tests/test_canvas.py +122 -0
  36. vispy/app/tests/test_context.py +92 -0
  37. vispy/app/tests/test_qt.py +47 -0
  38. vispy/app/tests/test_simultaneous.py +134 -0
  39. vispy/app/timer.py +174 -0
  40. vispy/color/__init__.py +17 -0
  41. vispy/color/_color_dict.py +193 -0
  42. vispy/color/color_array.py +447 -0
  43. vispy/color/color_space.py +181 -0
  44. vispy/color/colormap.py +1134 -0
  45. vispy/color/tests/__init__.py +0 -0
  46. vispy/color/tests/test_color.py +352 -0
  47. vispy/conftest.py +12 -0
  48. vispy/ext/__init__.py +0 -0
  49. vispy/ext/cocoapy.py +1542 -0
  50. vispy/ext/cubehelix.py +138 -0
  51. vispy/ext/egl.py +375 -0
  52. vispy/ext/fontconfig.py +118 -0
  53. vispy/ext/gdi32plus.py +206 -0
  54. vispy/ext/osmesa.py +105 -0
  55. vispy/geometry/__init__.py +23 -0
  56. vispy/geometry/_triangulation_debugger.py +171 -0
  57. vispy/geometry/calculations.py +134 -0
  58. vispy/geometry/curves.py +399 -0
  59. vispy/geometry/generation.py +643 -0
  60. vispy/geometry/isocurve.py +175 -0
  61. vispy/geometry/isosurface.py +465 -0
  62. vispy/geometry/meshdata.py +698 -0
  63. vispy/geometry/normals.py +78 -0
  64. vispy/geometry/parametric.py +56 -0
  65. vispy/geometry/polygon.py +137 -0
  66. vispy/geometry/rect.py +210 -0
  67. vispy/geometry/tests/__init__.py +0 -0
  68. vispy/geometry/tests/test_calculations.py +23 -0
  69. vispy/geometry/tests/test_generation.py +56 -0
  70. vispy/geometry/tests/test_meshdata.py +106 -0
  71. vispy/geometry/tests/test_triangulation.py +506 -0
  72. vispy/geometry/torusknot.py +142 -0
  73. vispy/geometry/triangulation.py +876 -0
  74. vispy/gloo/__init__.py +56 -0
  75. vispy/gloo/buffer.py +505 -0
  76. vispy/gloo/context.py +272 -0
  77. vispy/gloo/framebuffer.py +257 -0
  78. vispy/gloo/gl/__init__.py +234 -0
  79. vispy/gloo/gl/_constants.py +332 -0
  80. vispy/gloo/gl/_es2.py +986 -0
  81. vispy/gloo/gl/_gl2.py +1365 -0
  82. vispy/gloo/gl/_proxy.py +499 -0
  83. vispy/gloo/gl/_pyopengl2.py +362 -0
  84. vispy/gloo/gl/dummy.py +24 -0
  85. vispy/gloo/gl/es2.py +62 -0
  86. vispy/gloo/gl/gl2.py +98 -0
  87. vispy/gloo/gl/glplus.py +168 -0
  88. vispy/gloo/gl/pyopengl2.py +97 -0
  89. vispy/gloo/gl/tests/__init__.py +0 -0
  90. vispy/gloo/gl/tests/test_basics.py +282 -0
  91. vispy/gloo/gl/tests/test_functionality.py +566 -0
  92. vispy/gloo/gl/tests/test_names.py +246 -0
  93. vispy/gloo/gl/tests/test_use.py +71 -0
  94. vispy/gloo/glir.py +1816 -0
  95. vispy/gloo/globject.py +101 -0
  96. vispy/gloo/preprocessor.py +67 -0
  97. vispy/gloo/program.py +543 -0
  98. vispy/gloo/tests/__init__.py +0 -0
  99. vispy/gloo/tests/test_buffer.py +558 -0
  100. vispy/gloo/tests/test_context.py +119 -0
  101. vispy/gloo/tests/test_framebuffer.py +195 -0
  102. vispy/gloo/tests/test_glir.py +307 -0
  103. vispy/gloo/tests/test_globject.py +35 -0
  104. vispy/gloo/tests/test_program.py +302 -0
  105. vispy/gloo/tests/test_texture.py +732 -0
  106. vispy/gloo/tests/test_use_gloo.py +187 -0
  107. vispy/gloo/tests/test_util.py +60 -0
  108. vispy/gloo/tests/test_wrappers.py +261 -0
  109. vispy/gloo/texture.py +1045 -0
  110. vispy/gloo/util.py +129 -0
  111. vispy/gloo/wrappers.py +762 -0
  112. vispy/glsl/__init__.py +42 -0
  113. vispy/glsl/antialias/antialias.glsl +7 -0
  114. vispy/glsl/antialias/cap-butt.glsl +31 -0
  115. vispy/glsl/antialias/cap-round.glsl +29 -0
  116. vispy/glsl/antialias/cap-square.glsl +30 -0
  117. vispy/glsl/antialias/cap-triangle-in.glsl +30 -0
  118. vispy/glsl/antialias/cap-triangle-out.glsl +30 -0
  119. vispy/glsl/antialias/cap.glsl +67 -0
  120. vispy/glsl/antialias/caps.glsl +67 -0
  121. vispy/glsl/antialias/filled.glsl +50 -0
  122. vispy/glsl/antialias/outline.glsl +40 -0
  123. vispy/glsl/antialias/stroke.glsl +43 -0
  124. vispy/glsl/arrowheads/angle.glsl +99 -0
  125. vispy/glsl/arrowheads/arrowheads.frag +60 -0
  126. vispy/glsl/arrowheads/arrowheads.glsl +12 -0
  127. vispy/glsl/arrowheads/arrowheads.vert +83 -0
  128. vispy/glsl/arrowheads/curved.glsl +48 -0
  129. vispy/glsl/arrowheads/inhibitor.glsl +26 -0
  130. vispy/glsl/arrowheads/stealth.glsl +46 -0
  131. vispy/glsl/arrowheads/triangle.glsl +97 -0
  132. vispy/glsl/arrowheads/util.glsl +13 -0
  133. vispy/glsl/arrows/angle-30.glsl +12 -0
  134. vispy/glsl/arrows/angle-60.glsl +12 -0
  135. vispy/glsl/arrows/angle-90.glsl +12 -0
  136. vispy/glsl/arrows/arrow.frag +39 -0
  137. vispy/glsl/arrows/arrow.vert +49 -0
  138. vispy/glsl/arrows/arrows.glsl +17 -0
  139. vispy/glsl/arrows/common.glsl +187 -0
  140. vispy/glsl/arrows/curved.glsl +63 -0
  141. vispy/glsl/arrows/stealth.glsl +50 -0
  142. vispy/glsl/arrows/triangle-30.glsl +12 -0
  143. vispy/glsl/arrows/triangle-60.glsl +12 -0
  144. vispy/glsl/arrows/triangle-90.glsl +12 -0
  145. vispy/glsl/arrows/util.glsl +98 -0
  146. vispy/glsl/build_spatial_filters.py +660 -0
  147. vispy/glsl/collections/agg-fast-path.frag +20 -0
  148. vispy/glsl/collections/agg-fast-path.vert +78 -0
  149. vispy/glsl/collections/agg-glyph.frag +60 -0
  150. vispy/glsl/collections/agg-glyph.vert +33 -0
  151. vispy/glsl/collections/agg-marker.frag +35 -0
  152. vispy/glsl/collections/agg-marker.vert +48 -0
  153. vispy/glsl/collections/agg-path.frag +55 -0
  154. vispy/glsl/collections/agg-path.vert +166 -0
  155. vispy/glsl/collections/agg-point.frag +21 -0
  156. vispy/glsl/collections/agg-point.vert +35 -0
  157. vispy/glsl/collections/agg-segment.frag +32 -0
  158. vispy/glsl/collections/agg-segment.vert +75 -0
  159. vispy/glsl/collections/marker.frag +38 -0
  160. vispy/glsl/collections/marker.vert +48 -0
  161. vispy/glsl/collections/raw-path.frag +15 -0
  162. vispy/glsl/collections/raw-path.vert +24 -0
  163. vispy/glsl/collections/raw-point.frag +14 -0
  164. vispy/glsl/collections/raw-point.vert +31 -0
  165. vispy/glsl/collections/raw-segment.frag +18 -0
  166. vispy/glsl/collections/raw-segment.vert +26 -0
  167. vispy/glsl/collections/raw-triangle.frag +13 -0
  168. vispy/glsl/collections/raw-triangle.vert +26 -0
  169. vispy/glsl/collections/sdf-glyph-ticks.vert +69 -0
  170. vispy/glsl/collections/sdf-glyph.frag +80 -0
  171. vispy/glsl/collections/sdf-glyph.vert +59 -0
  172. vispy/glsl/collections/tick-labels.vert +71 -0
  173. vispy/glsl/colormaps/autumn.glsl +20 -0
  174. vispy/glsl/colormaps/blues.glsl +20 -0
  175. vispy/glsl/colormaps/color-space.glsl +17 -0
  176. vispy/glsl/colormaps/colormaps.glsl +24 -0
  177. vispy/glsl/colormaps/cool.glsl +20 -0
  178. vispy/glsl/colormaps/fire.glsl +21 -0
  179. vispy/glsl/colormaps/gray.glsl +20 -0
  180. vispy/glsl/colormaps/greens.glsl +20 -0
  181. vispy/glsl/colormaps/hot.glsl +22 -0
  182. vispy/glsl/colormaps/ice.glsl +20 -0
  183. vispy/glsl/colormaps/icefire.glsl +23 -0
  184. vispy/glsl/colormaps/parse.py +40 -0
  185. vispy/glsl/colormaps/reds.glsl +20 -0
  186. vispy/glsl/colormaps/spring.glsl +20 -0
  187. vispy/glsl/colormaps/summer.glsl +20 -0
  188. vispy/glsl/colormaps/user.glsl +22 -0
  189. vispy/glsl/colormaps/util.glsl +41 -0
  190. vispy/glsl/colormaps/wheel.glsl +21 -0
  191. vispy/glsl/colormaps/winter.glsl +20 -0
  192. vispy/glsl/lines/agg.frag +320 -0
  193. vispy/glsl/lines/agg.vert +241 -0
  194. vispy/glsl/markers/arrow.glsl +12 -0
  195. vispy/glsl/markers/asterisk.glsl +16 -0
  196. vispy/glsl/markers/chevron.glsl +14 -0
  197. vispy/glsl/markers/clover.glsl +20 -0
  198. vispy/glsl/markers/club.glsl +31 -0
  199. vispy/glsl/markers/cross.glsl +17 -0
  200. vispy/glsl/markers/diamond.glsl +12 -0
  201. vispy/glsl/markers/disc.glsl +9 -0
  202. vispy/glsl/markers/ellipse.glsl +67 -0
  203. vispy/glsl/markers/hbar.glsl +9 -0
  204. vispy/glsl/markers/heart.glsl +15 -0
  205. vispy/glsl/markers/infinity.glsl +15 -0
  206. vispy/glsl/markers/marker-sdf.frag +74 -0
  207. vispy/glsl/markers/marker-sdf.vert +41 -0
  208. vispy/glsl/markers/marker.frag +36 -0
  209. vispy/glsl/markers/marker.vert +46 -0
  210. vispy/glsl/markers/markers.glsl +24 -0
  211. vispy/glsl/markers/pin.glsl +18 -0
  212. vispy/glsl/markers/ring.glsl +11 -0
  213. vispy/glsl/markers/spade.glsl +28 -0
  214. vispy/glsl/markers/square.glsl +10 -0
  215. vispy/glsl/markers/tag.glsl +11 -0
  216. vispy/glsl/markers/triangle.glsl +14 -0
  217. vispy/glsl/markers/vbar.glsl +9 -0
  218. vispy/glsl/math/circle-through-2-points.glsl +30 -0
  219. vispy/glsl/math/constants.glsl +48 -0
  220. vispy/glsl/math/double.glsl +114 -0
  221. vispy/glsl/math/functions.glsl +20 -0
  222. vispy/glsl/math/point-to-line-distance.glsl +31 -0
  223. vispy/glsl/math/point-to-line-projection.glsl +29 -0
  224. vispy/glsl/math/signed-line-distance.glsl +27 -0
  225. vispy/glsl/math/signed-segment-distance.glsl +30 -0
  226. vispy/glsl/misc/regular-grid.frag +244 -0
  227. vispy/glsl/misc/spatial-filters.frag +1407 -0
  228. vispy/glsl/misc/viewport-NDC.glsl +20 -0
  229. vispy/glsl/transforms/azimuthal-equal-area.glsl +32 -0
  230. vispy/glsl/transforms/azimuthal-equidistant.glsl +38 -0
  231. vispy/glsl/transforms/hammer.glsl +44 -0
  232. vispy/glsl/transforms/identity.glsl +6 -0
  233. vispy/glsl/transforms/identity_forward.glsl +23 -0
  234. vispy/glsl/transforms/identity_inverse.glsl +23 -0
  235. vispy/glsl/transforms/linear-scale.glsl +127 -0
  236. vispy/glsl/transforms/log-scale.glsl +126 -0
  237. vispy/glsl/transforms/mercator-transverse-forward.glsl +40 -0
  238. vispy/glsl/transforms/mercator-transverse-inverse.glsl +40 -0
  239. vispy/glsl/transforms/panzoom.glsl +10 -0
  240. vispy/glsl/transforms/polar.glsl +41 -0
  241. vispy/glsl/transforms/position.glsl +44 -0
  242. vispy/glsl/transforms/power-scale.glsl +139 -0
  243. vispy/glsl/transforms/projection.glsl +7 -0
  244. vispy/glsl/transforms/pvm.glsl +13 -0
  245. vispy/glsl/transforms/rotate.glsl +45 -0
  246. vispy/glsl/transforms/trackball.glsl +15 -0
  247. vispy/glsl/transforms/translate.glsl +35 -0
  248. vispy/glsl/transforms/transverse_mercator.glsl +38 -0
  249. vispy/glsl/transforms/viewport-clipping.glsl +14 -0
  250. vispy/glsl/transforms/viewport-transform.glsl +16 -0
  251. vispy/glsl/transforms/viewport.glsl +50 -0
  252. vispy/glsl/transforms/x.glsl +24 -0
  253. vispy/glsl/transforms/y.glsl +19 -0
  254. vispy/glsl/transforms/z.glsl +14 -0
  255. vispy/io/__init__.py +20 -0
  256. vispy/io/_data/spatial-filters.npy +0 -0
  257. vispy/io/datasets.py +94 -0
  258. vispy/io/image.py +231 -0
  259. vispy/io/mesh.py +122 -0
  260. vispy/io/stl.py +167 -0
  261. vispy/io/tests/__init__.py +0 -0
  262. vispy/io/tests/test_image.py +47 -0
  263. vispy/io/tests/test_io.py +121 -0
  264. vispy/io/wavefront.py +350 -0
  265. vispy/plot/__init__.py +36 -0
  266. vispy/plot/fig.py +58 -0
  267. vispy/plot/plotwidget.py +522 -0
  268. vispy/plot/tests/__init__.py +0 -0
  269. vispy/plot/tests/test_plot.py +46 -0
  270. vispy/scene/__init__.py +43 -0
  271. vispy/scene/cameras/__init__.py +27 -0
  272. vispy/scene/cameras/_base.py +38 -0
  273. vispy/scene/cameras/arcball.py +106 -0
  274. vispy/scene/cameras/base_camera.py +538 -0
  275. vispy/scene/cameras/fly.py +474 -0
  276. vispy/scene/cameras/magnify.py +163 -0
  277. vispy/scene/cameras/panzoom.py +308 -0
  278. vispy/scene/cameras/perspective.py +333 -0
  279. vispy/scene/cameras/tests/__init__.py +0 -0
  280. vispy/scene/cameras/tests/test_cameras.py +27 -0
  281. vispy/scene/cameras/tests/test_link.py +53 -0
  282. vispy/scene/cameras/tests/test_perspective.py +122 -0
  283. vispy/scene/cameras/turntable.py +173 -0
  284. vispy/scene/canvas.py +639 -0
  285. vispy/scene/events.py +85 -0
  286. vispy/scene/node.py +644 -0
  287. vispy/scene/subscene.py +20 -0
  288. vispy/scene/tests/__init__.py +0 -0
  289. vispy/scene/tests/test_canvas.py +119 -0
  290. vispy/scene/tests/test_node.py +142 -0
  291. vispy/scene/tests/test_visuals.py +141 -0
  292. vispy/scene/visuals.py +276 -0
  293. vispy/scene/widgets/__init__.py +18 -0
  294. vispy/scene/widgets/anchor.py +25 -0
  295. vispy/scene/widgets/axis.py +88 -0
  296. vispy/scene/widgets/colorbar.py +176 -0
  297. vispy/scene/widgets/console.py +351 -0
  298. vispy/scene/widgets/grid.py +509 -0
  299. vispy/scene/widgets/label.py +50 -0
  300. vispy/scene/widgets/tests/__init__.py +0 -0
  301. vispy/scene/widgets/tests/test_colorbar.py +47 -0
  302. vispy/scene/widgets/viewbox.py +199 -0
  303. vispy/scene/widgets/widget.py +478 -0
  304. vispy/testing/__init__.py +51 -0
  305. vispy/testing/_runners.py +446 -0
  306. vispy/testing/_testing.py +416 -0
  307. vispy/testing/image_tester.py +473 -0
  308. vispy/testing/rendered_array_tester.py +85 -0
  309. vispy/testing/tests/__init__.py +0 -0
  310. vispy/testing/tests/test_testing.py +20 -0
  311. vispy/util/__init__.py +17 -0
  312. vispy/util/bunch.py +15 -0
  313. vispy/util/check_environment.py +57 -0
  314. vispy/util/config.py +490 -0
  315. vispy/util/dpi/__init__.py +19 -0
  316. vispy/util/dpi/_linux.py +69 -0
  317. vispy/util/dpi/_quartz.py +26 -0
  318. vispy/util/dpi/_win32.py +34 -0
  319. vispy/util/dpi/tests/__init__.py +0 -0
  320. vispy/util/dpi/tests/test_dpi.py +16 -0
  321. vispy/util/eq.py +41 -0
  322. vispy/util/event.py +774 -0
  323. vispy/util/fetching.py +276 -0
  324. vispy/util/filter.py +44 -0
  325. vispy/util/fonts/__init__.py +14 -0
  326. vispy/util/fonts/_freetype.py +73 -0
  327. vispy/util/fonts/_quartz.py +192 -0
  328. vispy/util/fonts/_triage.py +36 -0
  329. vispy/util/fonts/_vispy_fonts.py +20 -0
  330. vispy/util/fonts/_win32.py +105 -0
  331. vispy/util/fonts/data/OpenSans-Bold.ttf +0 -0
  332. vispy/util/fonts/data/OpenSans-BoldItalic.ttf +0 -0
  333. vispy/util/fonts/data/OpenSans-Italic.ttf +0 -0
  334. vispy/util/fonts/data/OpenSans-Regular.ttf +0 -0
  335. vispy/util/fonts/tests/__init__.py +0 -0
  336. vispy/util/fonts/tests/test_font.py +45 -0
  337. vispy/util/fourier.py +69 -0
  338. vispy/util/frozen.py +25 -0
  339. vispy/util/gallery_scraper.py +268 -0
  340. vispy/util/keys.py +91 -0
  341. vispy/util/logs.py +358 -0
  342. vispy/util/osmesa_gl.py +17 -0
  343. vispy/util/profiler.py +135 -0
  344. vispy/util/ptime.py +16 -0
  345. vispy/util/quaternion.py +229 -0
  346. vispy/util/svg/__init__.py +18 -0
  347. vispy/util/svg/base.py +20 -0
  348. vispy/util/svg/color.py +219 -0
  349. vispy/util/svg/element.py +51 -0
  350. vispy/util/svg/geometry.py +478 -0
  351. vispy/util/svg/group.py +66 -0
  352. vispy/util/svg/length.py +81 -0
  353. vispy/util/svg/number.py +25 -0
  354. vispy/util/svg/path.py +332 -0
  355. vispy/util/svg/shapes.py +57 -0
  356. vispy/util/svg/style.py +59 -0
  357. vispy/util/svg/svg.py +40 -0
  358. vispy/util/svg/transform.py +223 -0
  359. vispy/util/svg/transformable.py +28 -0
  360. vispy/util/svg/viewport.py +73 -0
  361. vispy/util/tests/__init__.py +0 -0
  362. vispy/util/tests/test_config.py +58 -0
  363. vispy/util/tests/test_docstring_parameters.py +123 -0
  364. vispy/util/tests/test_emitter_group.py +262 -0
  365. vispy/util/tests/test_event_emitter.py +743 -0
  366. vispy/util/tests/test_fourier.py +35 -0
  367. vispy/util/tests/test_gallery_scraper.py +112 -0
  368. vispy/util/tests/test_import.py +127 -0
  369. vispy/util/tests/test_key.py +22 -0
  370. vispy/util/tests/test_logging.py +45 -0
  371. vispy/util/tests/test_run.py +14 -0
  372. vispy/util/tests/test_transforms.py +42 -0
  373. vispy/util/tests/test_vispy.py +48 -0
  374. vispy/util/transforms.py +201 -0
  375. vispy/util/wrappers.py +155 -0
  376. vispy/version.py +4 -0
  377. vispy/visuals/__init__.py +50 -0
  378. vispy/visuals/_scalable_textures.py +485 -0
  379. vispy/visuals/axis.py +678 -0
  380. vispy/visuals/border.py +208 -0
  381. vispy/visuals/box.py +79 -0
  382. vispy/visuals/collections/__init__.py +30 -0
  383. vispy/visuals/collections/agg_fast_path_collection.py +219 -0
  384. vispy/visuals/collections/agg_path_collection.py +197 -0
  385. vispy/visuals/collections/agg_point_collection.py +52 -0
  386. vispy/visuals/collections/agg_segment_collection.py +142 -0
  387. vispy/visuals/collections/array_list.py +401 -0
  388. vispy/visuals/collections/base_collection.py +482 -0
  389. vispy/visuals/collections/collection.py +253 -0
  390. vispy/visuals/collections/path_collection.py +23 -0
  391. vispy/visuals/collections/point_collection.py +19 -0
  392. vispy/visuals/collections/polygon_collection.py +25 -0
  393. vispy/visuals/collections/raw_path_collection.py +119 -0
  394. vispy/visuals/collections/raw_point_collection.py +113 -0
  395. vispy/visuals/collections/raw_polygon_collection.py +77 -0
  396. vispy/visuals/collections/raw_segment_collection.py +112 -0
  397. vispy/visuals/collections/raw_triangle_collection.py +78 -0
  398. vispy/visuals/collections/segment_collection.py +19 -0
  399. vispy/visuals/collections/triangle_collection.py +16 -0
  400. vispy/visuals/collections/util.py +168 -0
  401. vispy/visuals/colorbar.py +699 -0
  402. vispy/visuals/cube.py +41 -0
  403. vispy/visuals/ellipse.py +163 -0
  404. vispy/visuals/filters/__init__.py +10 -0
  405. vispy/visuals/filters/base_filter.py +242 -0
  406. vispy/visuals/filters/clipper.py +60 -0
  407. vispy/visuals/filters/clipping_planes.py +122 -0
  408. vispy/visuals/filters/color.py +181 -0
  409. vispy/visuals/filters/markers.py +28 -0
  410. vispy/visuals/filters/mesh.py +796 -0
  411. vispy/visuals/filters/picking.py +60 -0
  412. vispy/visuals/filters/tests/__init__.py +3 -0
  413. vispy/visuals/filters/tests/test_primitive_picking_filters.py +70 -0
  414. vispy/visuals/filters/tests/test_wireframe_filter.py +16 -0
  415. vispy/visuals/glsl/__init__.py +1 -0
  416. vispy/visuals/glsl/antialiasing.py +133 -0
  417. vispy/visuals/glsl/color.py +63 -0
  418. vispy/visuals/graphs/__init__.py +1 -0
  419. vispy/visuals/graphs/graph.py +240 -0
  420. vispy/visuals/graphs/layouts/__init__.py +55 -0
  421. vispy/visuals/graphs/layouts/circular.py +49 -0
  422. vispy/visuals/graphs/layouts/force_directed.py +211 -0
  423. vispy/visuals/graphs/layouts/networkx_layout.py +87 -0
  424. vispy/visuals/graphs/layouts/random.py +52 -0
  425. vispy/visuals/graphs/tests/__init__.py +1 -0
  426. vispy/visuals/graphs/tests/test_layouts.py +139 -0
  427. vispy/visuals/graphs/tests/test_networkx_layout.py +47 -0
  428. vispy/visuals/graphs/util.py +120 -0
  429. vispy/visuals/gridlines.py +105 -0
  430. vispy/visuals/gridmesh.py +98 -0
  431. vispy/visuals/histogram.py +58 -0
  432. vispy/visuals/image.py +688 -0
  433. vispy/visuals/image_complex.py +130 -0
  434. vispy/visuals/infinite_line.py +199 -0
  435. vispy/visuals/instanced_mesh.py +152 -0
  436. vispy/visuals/isocurve.py +213 -0
  437. vispy/visuals/isoline.py +241 -0
  438. vispy/visuals/isosurface.py +113 -0
  439. vispy/visuals/line/__init__.py +6 -0
  440. vispy/visuals/line/arrow.py +289 -0
  441. vispy/visuals/line/dash_atlas.py +90 -0
  442. vispy/visuals/line/line.py +545 -0
  443. vispy/visuals/line_plot.py +135 -0
  444. vispy/visuals/linear_region.py +199 -0
  445. vispy/visuals/markers.py +810 -0
  446. vispy/visuals/mesh.py +373 -0
  447. vispy/visuals/mesh_normals.py +159 -0
  448. vispy/visuals/plane.py +54 -0
  449. vispy/visuals/polygon.py +145 -0
  450. vispy/visuals/rectangle.py +196 -0
  451. vispy/visuals/regular_polygon.py +56 -0
  452. vispy/visuals/scrolling_lines.py +197 -0
  453. vispy/visuals/shaders/__init__.py +17 -0
  454. vispy/visuals/shaders/compiler.py +206 -0
  455. vispy/visuals/shaders/expression.py +99 -0
  456. vispy/visuals/shaders/function.py +788 -0
  457. vispy/visuals/shaders/multiprogram.py +145 -0
  458. vispy/visuals/shaders/parsing.py +140 -0
  459. vispy/visuals/shaders/program.py +161 -0
  460. vispy/visuals/shaders/shader_object.py +162 -0
  461. vispy/visuals/shaders/tests/__init__.py +0 -0
  462. vispy/visuals/shaders/tests/test_function.py +486 -0
  463. vispy/visuals/shaders/tests/test_multiprogram.py +78 -0
  464. vispy/visuals/shaders/tests/test_parsing.py +57 -0
  465. vispy/visuals/shaders/variable.py +272 -0
  466. vispy/visuals/spectrogram.py +169 -0
  467. vispy/visuals/sphere.py +80 -0
  468. vispy/visuals/surface_plot.py +192 -0
  469. vispy/visuals/tests/__init__.py +0 -0
  470. vispy/visuals/tests/test_arrows.py +109 -0
  471. vispy/visuals/tests/test_axis.py +120 -0
  472. vispy/visuals/tests/test_collections.py +15 -0
  473. vispy/visuals/tests/test_colorbar.py +179 -0
  474. vispy/visuals/tests/test_colormap.py +97 -0
  475. vispy/visuals/tests/test_ellipse.py +122 -0
  476. vispy/visuals/tests/test_histogram.py +24 -0
  477. vispy/visuals/tests/test_image.py +390 -0
  478. vispy/visuals/tests/test_image_complex.py +36 -0
  479. vispy/visuals/tests/test_infinite_line.py +53 -0
  480. vispy/visuals/tests/test_instanced_mesh.py +50 -0
  481. vispy/visuals/tests/test_isosurface.py +22 -0
  482. vispy/visuals/tests/test_linear_region.py +152 -0
  483. vispy/visuals/tests/test_markers.py +54 -0
  484. vispy/visuals/tests/test_mesh.py +261 -0
  485. vispy/visuals/tests/test_mesh_normals.py +218 -0
  486. vispy/visuals/tests/test_polygon.py +112 -0
  487. vispy/visuals/tests/test_rectangle.py +163 -0
  488. vispy/visuals/tests/test_regular_polygon.py +111 -0
  489. vispy/visuals/tests/test_scalable_textures.py +180 -0
  490. vispy/visuals/tests/test_sdf.py +73 -0
  491. vispy/visuals/tests/test_spectrogram.py +42 -0
  492. vispy/visuals/tests/test_text.py +95 -0
  493. vispy/visuals/tests/test_volume.py +542 -0
  494. vispy/visuals/tests/test_windbarb.py +33 -0
  495. vispy/visuals/text/__init__.py +7 -0
  496. vispy/visuals/text/_sdf_cpu.cpython-311-darwin.so +0 -0
  497. vispy/visuals/text/_sdf_cpu.pyx +110 -0
  498. vispy/visuals/text/_sdf_gpu.py +316 -0
  499. vispy/visuals/text/text.py +675 -0
  500. vispy/visuals/transforms/__init__.py +34 -0
  501. vispy/visuals/transforms/_util.py +191 -0
  502. vispy/visuals/transforms/base_transform.py +233 -0
  503. vispy/visuals/transforms/chain.py +300 -0
  504. vispy/visuals/transforms/interactive.py +98 -0
  505. vispy/visuals/transforms/linear.py +564 -0
  506. vispy/visuals/transforms/nonlinear.py +398 -0
  507. vispy/visuals/transforms/tests/__init__.py +0 -0
  508. vispy/visuals/transforms/tests/test_transforms.py +243 -0
  509. vispy/visuals/transforms/transform_system.py +339 -0
  510. vispy/visuals/tube.py +173 -0
  511. vispy/visuals/visual.py +923 -0
  512. vispy/visuals/volume.py +1335 -0
  513. vispy/visuals/windbarb.py +291 -0
  514. vispy/visuals/xyz_axis.py +34 -0
  515. vispy-0.14.0.dist-info/LICENSE.txt +36 -0
  516. vispy-0.14.0.dist-info/METADATA +218 -0
  517. vispy-0.14.0.dist-info/RECORD +519 -0
  518. vispy-0.14.0.dist-info/WHEEL +5 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
vispy/visuals/cube.py ADDED
@@ -0,0 +1,41 @@
1
+ # -*- coding: utf-8 -*-
2
+ # -----------------------------------------------------------------------------
3
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
4
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
5
+ # -----------------------------------------------------------------------------
6
+
7
+ import warnings
8
+ from .box import BoxVisual
9
+
10
+
11
+ class CubeVisual(BoxVisual):
12
+ """Visual that displays a cube or cuboid
13
+
14
+ Parameters
15
+ ----------
16
+ size : float or tuple
17
+ The size of the cuboid. A float gives a cube, whereas tuples may
18
+ specify the size of each axis (x, y, z) independently.
19
+ vertex_colors : ndarray
20
+ Same as for `MeshVisual` class. See `create_cube` for vertex ordering.
21
+ face_colors : ndarray
22
+ Same as for `MeshVisual` class. See `create_cube` for vertex ordering.
23
+ color : Color
24
+ The `Color` to use when drawing the cube faces.
25
+ edge_color : tuple or Color
26
+ The `Color` to use when drawing the cube edges. If `None`, then no
27
+ cube edges are drawn.
28
+ """
29
+
30
+ def __init__(self, size=1.0, vertex_colors=None, face_colors=None,
31
+ color=(0.5, 0.5, 1, 1), edge_color=None, **kwargs):
32
+ warnings.warn("The CubeVisual is deprecated in favor of BoxVisual",
33
+ DeprecationWarning, stacklevel=2)
34
+ if isinstance(size, tuple):
35
+ width, height, depth = size
36
+ else:
37
+ width = height = depth = size
38
+ BoxVisual.__init__(self, width=width, height=height, depth=depth,
39
+ vertex_colors=vertex_colors,
40
+ face_colors=face_colors, color=color,
41
+ edge_color=edge_color, **kwargs)
@@ -0,0 +1,163 @@
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
+ """Simple ellipse visual based on PolygonVisual"""
7
+
8
+ from __future__ import division
9
+
10
+ import numpy as np
11
+ from .polygon import PolygonVisual
12
+
13
+
14
+ class EllipseVisual(PolygonVisual):
15
+ """
16
+ Displays a 2D ellipse
17
+
18
+ Parameters
19
+ ----------
20
+ center : array
21
+ Center of the ellipse
22
+ color : instance of Color
23
+ The face color to use.
24
+ border_color : instance of Color
25
+ The border color to use.
26
+ border_width: float
27
+ The width of the border in pixels
28
+ Line widths > 1px are only
29
+ guaranteed to work when using `border_method='agg'` method.
30
+ radius : float | tuple
31
+ Radius or radii of the ellipse
32
+ Defaults to (0.1, 0.1)
33
+ start_angle : float
34
+ Start angle of the ellipse in degrees
35
+ Defaults to 0.
36
+ span_angle : float
37
+ Span angle of the ellipse in degrees
38
+ Defaults to 360.
39
+ num_segments : int
40
+ Number of segments to be used to draw the ellipse
41
+ Defaults to 100
42
+ **kwargs : dict
43
+ Keyword arguments to pass to `PolygonVisual`.
44
+ """
45
+
46
+ def __init__(self, center=None, color='black', border_color=None,
47
+ border_width=1, radius=(0.1, 0.1), start_angle=0.,
48
+ span_angle=360., num_segments=100, **kwargs):
49
+ self._center = center
50
+ self._radius = radius
51
+ self._start_angle = start_angle
52
+ self._span_angle = span_angle
53
+ self._num_segments = num_segments
54
+
55
+ # triangulation can be very slow
56
+ kwargs.setdefault('triangulate', False)
57
+ PolygonVisual.__init__(self, pos=None, color=color,
58
+ border_color=border_color,
59
+ border_width=border_width, **kwargs)
60
+
61
+ self._mesh.mode = "triangle_fan"
62
+ self._regen_pos()
63
+ self._update()
64
+
65
+ @staticmethod
66
+ def _generate_vertices(center, radius, start_angle, span_angle,
67
+ num_segments):
68
+ if isinstance(radius, (list, tuple)):
69
+ if len(radius) == 2:
70
+ xr, yr = radius
71
+ else:
72
+ raise ValueError("radius must be float or 2 value tuple/list"
73
+ " (got %s of length %d)" % (type(radius),
74
+ len(radius)))
75
+ else:
76
+ xr = yr = radius
77
+
78
+ start_angle = np.deg2rad(start_angle)
79
+
80
+ vertices = np.empty([num_segments + 2, 2], dtype=np.float32)
81
+
82
+ # split the total angle into num_segments instances
83
+ theta = np.linspace(start_angle,
84
+ start_angle + np.deg2rad(span_angle),
85
+ num_segments + 1)
86
+
87
+ # PolarProjection
88
+ vertices[1:, 0] = center[0] + xr * np.cos(theta)
89
+ vertices[1:, 1] = center[1] + yr * np.sin(theta)
90
+
91
+ # specify center point (not used in border)
92
+ vertices[0] = np.float32([center[0], center[1]])
93
+
94
+ return vertices
95
+
96
+ @property
97
+ def center(self):
98
+ """The center of the ellipse"""
99
+ return self._center
100
+
101
+ @center.setter
102
+ def center(self, center):
103
+ """The center of the ellipse"""
104
+ self._center = center
105
+ self._regen_pos()
106
+ self._update()
107
+
108
+ @property
109
+ def radius(self):
110
+ """The start radii of the ellipse."""
111
+ return self._radius
112
+
113
+ @radius.setter
114
+ def radius(self, radius):
115
+ self._radius = radius
116
+ self._regen_pos()
117
+ self._update()
118
+
119
+ @property
120
+ def start_angle(self):
121
+ """The start start_angle of the ellipse."""
122
+ return self._start_angle
123
+
124
+ @start_angle.setter
125
+ def start_angle(self, start_angle):
126
+ self._start_angle = start_angle
127
+ self._regen_pos()
128
+ self._update()
129
+
130
+ @property
131
+ def span_angle(self):
132
+ """The angular span of the ellipse."""
133
+ return self._span_angle
134
+
135
+ @span_angle.setter
136
+ def span_angle(self, span_angle):
137
+ self._span_angle = span_angle
138
+ self._regen_pos()
139
+ self._update()
140
+
141
+ @property
142
+ def num_segments(self):
143
+ """The number of segments in the ellipse."""
144
+ return self._num_segments
145
+
146
+ @num_segments.setter
147
+ def num_segments(self, num_segments):
148
+ num_segments = int(num_segments)
149
+ if num_segments < 1:
150
+ raise ValueError('EllipseVisual must consist of more than 1 '
151
+ 'segment')
152
+ self._num_segments = num_segments
153
+ self._regen_pos()
154
+ self._update()
155
+
156
+ def _regen_pos(self):
157
+ vertices = self._generate_vertices(center=self._center,
158
+ radius=self._radius,
159
+ start_angle=self._start_angle,
160
+ span_angle=self._span_angle,
161
+ num_segments=self._num_segments)
162
+ # don't use the center point
163
+ self._pos = vertices[1:]
@@ -0,0 +1,10 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from .base_filter import Filter, PrimitivePickingFilter # noqa
6
+ from .clipper import Clipper # noqa
7
+ from .color import Alpha, ColorFilter, IsolineFilter, ZColormapFilter # noqa
8
+ from .picking import PickingFilter # noqa
9
+ from .markers import MarkerPickingFilter # noqa
10
+ from .mesh import TextureFilter, ShadingFilter, InstancedShadingFilter, WireframeFilter, FacePickingFilter # noqa
@@ -0,0 +1,242 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from abc import ABCMeta, abstractmethod
6
+
7
+ import numpy as np
8
+
9
+ from vispy.gloo import VertexBuffer
10
+ from ..shaders import Function
11
+
12
+
13
+ class BaseFilter(object):
14
+ """Superclass for all filters."""
15
+
16
+ def _attach(self, visual):
17
+ """Called when a filter should be attached to a visual.
18
+
19
+ Parameters
20
+ ----------
21
+ visual : instance of BaseVisual
22
+ The visual that called this.
23
+ """
24
+ raise NotImplementedError(self)
25
+
26
+ def _detach(self, visual):
27
+ """Called when a filter should be detached from a visual.
28
+
29
+ Parameters
30
+ ----------
31
+ visual : instance of BaseVisual
32
+ The visual that called this.
33
+ """
34
+ raise NotImplementedError(self)
35
+
36
+
37
+ class Filter(BaseFilter):
38
+ """Base class for all filters that use fragment and/or vertex shaders.
39
+
40
+ Parameters
41
+ ----------
42
+ vcode : str | Function | None
43
+ Vertex shader code. If None, ``vhook`` and ``vpos`` will
44
+ be ignored.
45
+ vhook : {'pre', 'post'}
46
+ Hook name to attach the vertex shader to.
47
+ vpos : int
48
+ Position in the hook to attach the vertex shader.
49
+ fcode : str | Function | None
50
+ Fragment shader code. If None, ``fhook`` and ``fpos`` will
51
+ be ignored.
52
+ fhook : {'pre', 'post'}
53
+ Hook name to attach the fragment shader to.
54
+ fpos : int
55
+ Position in the hook to attach the fragment shader.
56
+
57
+ Attributes
58
+ ----------
59
+ vshader : Function | None
60
+ Vertex shader.
61
+ fshader : Function | None
62
+ Fragment shader.
63
+ """
64
+
65
+ def __init__(self, vcode=None, vhook='post', vpos=5,
66
+ fcode=None, fhook='post', fpos=5):
67
+ super(Filter, self).__init__()
68
+
69
+ if vcode is not None:
70
+ self.vshader = Function(vcode) if isinstance(vcode, str) else vcode
71
+ self._vexpr = self.vshader()
72
+ self._vhook = vhook
73
+ self._vpos = vpos
74
+ else:
75
+ self.vshader = None
76
+
77
+ if fcode is not None:
78
+ self.fshader = Function(fcode) if isinstance(fcode, str) else fcode
79
+ self._fexpr = self.fshader()
80
+ self._fhook = fhook
81
+ self._fpos = fpos
82
+ else:
83
+ self.fshader = None
84
+
85
+ self._attached = False
86
+
87
+ @property
88
+ def attached(self):
89
+ return self._attached
90
+
91
+ def _attach(self, visual):
92
+ """Called when a filter should be attached to a visual.
93
+
94
+ Parameters
95
+ ----------
96
+ visual : instance of Visual
97
+ The visual that called this.
98
+ """
99
+ if self.vshader:
100
+ hook = visual._get_hook('vert', self._vhook)
101
+ hook.add(self._vexpr, position=self._vpos)
102
+
103
+ if self.fshader:
104
+ hook = visual._get_hook('frag', self._fhook)
105
+ hook.add(self._fexpr, position=self._fpos)
106
+
107
+ self._attached = True
108
+ self._visual = visual
109
+
110
+ def _detach(self, visual):
111
+ """Called when a filter should be detached from a visual.
112
+
113
+ Parameters
114
+ ----------
115
+ visual : instance of Visual
116
+ The visual that called this.
117
+ """
118
+ if self.vshader:
119
+ hook = visual._get_hook('vert', self._vhook)
120
+ hook.remove(self._vexpr)
121
+
122
+ if self.fshader:
123
+ hook = visual._get_hook('frag', self._fhook)
124
+ hook.remove(self._fexpr)
125
+
126
+ self._attached = False
127
+ self._visual = None
128
+
129
+
130
+ class PrimitivePickingFilter(Filter, metaclass=ABCMeta):
131
+ """Abstract base class for Visual-specific filters to implement a
132
+ primitive-picking mode.
133
+
134
+ Subclasses must (and usually only need to) implement
135
+ :py:meth:`_get_picking_ids`.
136
+ """
137
+
138
+ def __init__(self, fpos=9, *, discard_transparent=False):
139
+ # fpos is set to 9 by default to put it near the end, but before the
140
+ # default PickingFilter
141
+ vfunc = Function("""\
142
+ varying vec4 v_marker_picking_color;
143
+ void prepare_marker_picking() {
144
+ v_marker_picking_color = $ids;
145
+ }
146
+ """)
147
+ ffunc = Function("""\
148
+ varying vec4 v_marker_picking_color;
149
+ void marker_picking_filter() {
150
+ if ( $enabled != 1 ) {
151
+ return;
152
+ }
153
+ if ( $discard_transparent == 1 && gl_FragColor.a == 0.0 ) {
154
+ discard;
155
+ }
156
+ gl_FragColor = v_marker_picking_color;
157
+ }
158
+ """)
159
+
160
+ self._id_colors = VertexBuffer(np.zeros((0, 4), dtype=np.float32))
161
+ vfunc['ids'] = self._id_colors
162
+ self._n_primitives = 0
163
+ super().__init__(vcode=vfunc, fcode=ffunc, fpos=fpos)
164
+ self.enabled = False
165
+ self.discard_transparent = discard_transparent
166
+
167
+ @abstractmethod
168
+ def _get_picking_ids(self):
169
+ """Return a 1D array of picking IDs for the vertices in the visual.
170
+
171
+ Generally, this method should be implemented to:
172
+ 1. Calculate the number of primitives in the visual (may be
173
+ persisted in `self._n_primitives`).
174
+ 2. Calculate a range of picking ids for each primitive in the
175
+ visual. IDs should start from 1, reserving 0 for the background. If
176
+ primitives comprise multiple vertices (triangles), ids may need to
177
+ be repeated.
178
+
179
+ The return value should be an array of uint32 with shape
180
+ (num_vertices,).
181
+
182
+ If no change to the picking IDs is needed (for example, the number of
183
+ primitives has not changed), this method should return `None`.
184
+ """
185
+ raise NotImplementedError(self)
186
+
187
+ def _update_id_colors(self):
188
+ """Calculate the colors encoding the picking IDs for the visual.
189
+
190
+ For performance, this method will not update the id colors VertexBuffer
191
+ if :py:meth:`_get_picking_ids` returns `None`.
192
+ """
193
+ # this should remain untouched
194
+ ids = self._get_picking_ids()
195
+ if ids is not None:
196
+ id_colors = self._pack_ids_into_rgba(ids)
197
+ self._id_colors.set_data(id_colors)
198
+
199
+ @staticmethod
200
+ def _pack_ids_into_rgba(ids):
201
+ """Pack an array of uint32 primitive ids into float32 RGBA colors."""
202
+ if ids.dtype != np.uint32:
203
+ raise ValueError(f"ids must be uint32, got {ids.dtype}")
204
+
205
+ return np.divide(
206
+ ids.view(np.uint8).reshape(-1, 4),
207
+ 255,
208
+ dtype=np.float32
209
+ )
210
+
211
+ def _on_data_updated(self, event=None):
212
+ if not self.attached:
213
+ return
214
+ self._update_id_colors()
215
+
216
+ @property
217
+ def enabled(self):
218
+ return self._enabled
219
+
220
+ @enabled.setter
221
+ def enabled(self, e):
222
+ self._enabled = bool(e)
223
+ self.fshader['enabled'] = int(self._enabled)
224
+ self._on_data_updated()
225
+
226
+ @property
227
+ def discard_transparent(self):
228
+ return self._discard_transparent
229
+
230
+ @discard_transparent.setter
231
+ def discard_transparent(self, d):
232
+ self._discard_transparent = bool(d)
233
+ self.fshader['discard_transparent'] = int(self._discard_transparent)
234
+
235
+ def _attach(self, visual):
236
+ super()._attach(visual)
237
+ visual.events.data_updated.connect(self._on_data_updated)
238
+ self._on_data_updated()
239
+
240
+ def _detach(self, visual):
241
+ visual.events.data_updated.disconnect(self._on_data_updated)
242
+ super()._detach(visual)
@@ -0,0 +1,60 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from .base_filter import Filter
6
+ from ..transforms import NullTransform
7
+ from ...geometry import Rect
8
+
9
+
10
+ class Clipper(Filter):
11
+ """Clips visual output to a rectangular region."""
12
+
13
+ FRAG_SHADER = """
14
+ void clip() {
15
+ vec4 pos = $fb_to_clip(gl_FragCoord);
16
+ if( pos.x < $view.x || pos.x > $view.y ||
17
+ pos.y < $view.z || pos.y > $view.w ) {
18
+ discard;
19
+ }
20
+ }
21
+ """
22
+
23
+ def __init__(self, bounds=(0, 0, 1, 1), transform=None):
24
+ super(Clipper, self).__init__(fcode=self.FRAG_SHADER,
25
+ fhook='pre', fpos=1)
26
+
27
+ self.bounds = bounds # (x, y, w, h)
28
+ if transform is None:
29
+ transform = NullTransform()
30
+ self._transform = None
31
+ self.transform = transform
32
+
33
+ @property
34
+ def bounds(self):
35
+ """The clipping boundaries.
36
+
37
+ This must be a tuple (x, y, w, h) in a clipping coordinate system
38
+ that is defined by the `transform` property.
39
+ """
40
+ return self._bounds
41
+
42
+ @bounds.setter
43
+ def bounds(self, b):
44
+ self._bounds = Rect(b).normalized()
45
+ b = self._bounds
46
+ self.fshader['view'] = (b.left, b.right, b.bottom, b.top)
47
+
48
+ @property
49
+ def transform(self):
50
+ """The transform that maps from framebuffer coordinates to clipping
51
+ coordinates.
52
+ """
53
+ return self._transform
54
+
55
+ @transform.setter
56
+ def transform(self, tr):
57
+ if tr is self._transform:
58
+ return
59
+ self._transform = tr
60
+ self.fshader['fb_to_clip'] = tr
@@ -0,0 +1,122 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from __future__ import annotations
6
+
7
+ from typing import Optional
8
+
9
+ from functools import lru_cache
10
+
11
+ import numpy as np
12
+
13
+ from ..shaders import Function, Varying
14
+ from .base_filter import Filter
15
+
16
+
17
+ class PlanesClipper(Filter):
18
+ """Clips visual output based on arbitrary clipping planes.
19
+
20
+ Parameters
21
+ ----------
22
+ cliping_planes : ArrayLike
23
+ Each plane is defined by a position and a normal vector (magnitude is irrelevant). Shape: (n_planes, 2, 3)
24
+ coord_system : str
25
+ Coordinate system used by the clipping planes (see visuals.transforms.transform_system.py)
26
+
27
+ """
28
+
29
+ VERT_CODE = """
30
+ void clip() {
31
+ // pass position as varying for interpolation
32
+ $v_position = gl_Position;
33
+ }
34
+ """
35
+
36
+ FRAG_CODE = """
37
+ void clip() {
38
+ float distance_from_clip = $clip_with_planes($itransform($v_position).xyz);
39
+ if (distance_from_clip < 0.)
40
+ discard;
41
+ }
42
+ """
43
+
44
+ def __init__(self, clipping_planes: Optional[np.ndarray] = None, coord_system: str = 'scene'):
45
+ tr = ['visual', 'scene', 'document', 'canvas', 'framebuffer', 'render']
46
+ if coord_system not in tr:
47
+ raise ValueError(f'Invalid coordinate system {coord_system}. Must be one of {tr}.')
48
+ self._coord_system = coord_system
49
+
50
+ super().__init__(
51
+ vcode=Function(self.VERT_CODE), vhook='post', vpos=1,
52
+ fcode=Function(self.FRAG_CODE), fhook='pre', fpos=1,
53
+ )
54
+
55
+ # initialize clipping planes
56
+ self._clipping_planes = np.empty((0, 2, 3), dtype=np.float32)
57
+ self._clipping_planes_func = Function(self._build_clipping_planes_glsl(0))
58
+ self.fshader['clip_with_planes'] = self._clipping_planes_func
59
+
60
+ v_position = Varying('v_position', 'vec4')
61
+ self.vshader['v_position'] = v_position
62
+ self.fshader['v_position'] = v_position
63
+
64
+ self.clipping_planes = clipping_planes
65
+
66
+ @property
67
+ def coord_system(self) -> str:
68
+ """
69
+ Coordinate system used by the clipping planes (see visuals.transforms.transform_system.py)
70
+ """
71
+ # unsettable cause we can't update the transform after being attached
72
+ return self._coord_system
73
+
74
+ def _attach(self, visual):
75
+ super()._attach(visual)
76
+ self.fshader['itransform'] = visual.get_transform('render', self._coord_system)
77
+
78
+ @staticmethod
79
+ @lru_cache(maxsize=10)
80
+ def _build_clipping_planes_glsl(n_planes: int) -> str:
81
+ """Build the code snippet used to clip the volume based on self.clipping_planes."""
82
+ func_template = '''
83
+ float clip_planes(vec3 loc) {{
84
+ float distance_from_clip = 3.4e38; // max float
85
+ {clips};
86
+ return distance_from_clip;
87
+ }}
88
+ '''
89
+ # the vertex is considered clipped if on the "negative" side of the plane
90
+ clip_template = '''
91
+ vec3 relative_vec{idx} = loc - $clipping_plane_pos{idx};
92
+ float distance_from_clip{idx} = dot(relative_vec{idx}, $clipping_plane_norm{idx});
93
+ distance_from_clip = min(distance_from_clip{idx}, distance_from_clip);
94
+ '''
95
+ all_clips = []
96
+ for idx in range(n_planes):
97
+ all_clips.append(clip_template.format(idx=idx))
98
+ formatted_code = func_template.format(clips=''.join(all_clips))
99
+ return formatted_code
100
+
101
+ @property
102
+ def clipping_planes(self) -> np.ndarray:
103
+ """Get the set of planes used to clip the mesh.
104
+ Each plane is defined by a position and a normal vector (magnitude is irrelevant). Shape: (n_planes, 2, 3)
105
+ """
106
+ return self._clipping_planes
107
+
108
+ @clipping_planes.setter
109
+ def clipping_planes(self, value: Optional[np.ndarray]):
110
+ if value is None:
111
+ value = np.empty((0, 2, 3), dtype=np.float32)
112
+
113
+ # only recreate function if amount of clipping planes changes
114
+ if len(value) != len(self._clipping_planes):
115
+ self._clipping_planes_func = Function(self._build_clipping_planes_glsl(len(value)))
116
+ self.fshader['clip_with_planes'] = self._clipping_planes_func
117
+
118
+ self._clipping_planes = value
119
+
120
+ for idx, plane in enumerate(value):
121
+ self._clipping_planes_func[f'clipping_plane_pos{idx}'] = tuple(plane[0])
122
+ self._clipping_planes_func[f'clipping_plane_norm{idx}'] = tuple(plane[1])