vispy 0.15.0__cp313-cp313-manylinux_2_17_x86_64.manylinux2014_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-313-x86_64-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,474 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) Vispy Development Team. All Rights Reserved.
3
+ # Distributed under the (new) BSD License. See LICENSE.txt for more info.
4
+
5
+ from __future__ import division
6
+
7
+ import math
8
+ import numpy as np
9
+
10
+ from ...app import Timer
11
+ from ...util.quaternion import Quaternion
12
+ from ...util import keys
13
+ from .perspective import PerspectiveCamera
14
+
15
+
16
+ class FlyCamera(PerspectiveCamera):
17
+ """The fly camera provides a way to explore 3D data using an
18
+ interaction style that resembles a flight simulator.
19
+
20
+ For this camera, the ``scale_factor`` indicates the speed of the
21
+ camera in units per second, and the ``center`` indicates the
22
+ position of the camera.
23
+
24
+ Parameters
25
+ ----------
26
+ fov : float
27
+ Field of view. Default 60.0.
28
+ rotation : float | None
29
+ Rotation to use.
30
+ **kwargs : dict
31
+ Keyword arguments to pass to `BaseCamera`.
32
+
33
+ Notes
34
+ -----
35
+ Interacting with this camera might need a bit of practice.
36
+ The reaction to key presses can be customized by modifying the
37
+ keymap property.
38
+
39
+ Moving:
40
+
41
+ * arrow keys, or WASD to move forward, backward, left and right
42
+ * F and C keys move up and down
43
+ * Space bar to brake
44
+
45
+ Viewing:
46
+
47
+ * Use the mouse while holding down LMB to control the pitch and yaw.
48
+ * Alternatively, the pitch and yaw can be changed using the keys
49
+ IKJL
50
+ * The camera auto-rotates to make the bottom point down, manual
51
+ rolling can be performed using Q and E.
52
+
53
+ """
54
+
55
+ # Using _rotation1 and _rotation2 for camera states instead of _rotation
56
+ _state_props = PerspectiveCamera._state_props + ('rotation1', 'rotation2')
57
+
58
+ def __init__(self, fov=60, rotation=None, **kwargs):
59
+
60
+ # Motion speed vector
61
+ self._speed = np.zeros((6,), 'float64')
62
+ self._distance = None
63
+
64
+ # Acceleration and braking vectors, set from keyboard
65
+ self._brake = np.zeros((6,), 'uint8') # bool-ish
66
+ self._acc = np.zeros((6,), 'float64')
67
+
68
+ # Init rotations
69
+ self._auto_roll = True # Whether to roll to make Z up
70
+ self._rotation1 = Quaternion() # The base rotation
71
+ self._rotation2 = Quaternion() # The delta yaw and pitch rotation
72
+
73
+ PerspectiveCamera.__init__(self, fov=fov, **kwargs)
74
+
75
+ # Set camera attributes
76
+ self.rotation1 = rotation.normalize() if (rotation is not None) else Quaternion()
77
+
78
+ # To store data at start of interaction
79
+ self._event_value = None
80
+
81
+ # Whether the mouse-system wants a transform update
82
+ self._update_from_mouse = False
83
+
84
+ # Mapping that defines keys to thrusters
85
+ self._keymap = {
86
+ keys.UP: (+1, 1), keys.DOWN: (-1, 1),
87
+ keys.RIGHT: (+1, 2), keys.LEFT: (-1, 2),
88
+ #
89
+ 'W': (+1, 1), 'S': (-1, 1),
90
+ 'D': (+1, 2), 'A': (-1, 2),
91
+ 'F': (+1, 3), 'C': (-1, 3),
92
+ #
93
+ 'I': (+1, 4), 'K': (-1, 4),
94
+ 'L': (+1, 5), 'J': (-1, 5),
95
+ 'Q': (+1, 6), 'E': (-1, 6),
96
+ #
97
+ keys.SPACE: (0, 1, 2, 3), # 0 means brake, apply to translation
98
+ # keys.ALT: (+5, 1), # Turbo
99
+ }
100
+
101
+ # Timer. Each tick we calculate new speed and new position
102
+ self._timer = Timer(0.01, start=False, connect=self.on_timer)
103
+
104
+ @property
105
+ def rotation(self):
106
+ """Get the full rotation. This rotation is composed of the
107
+ normal rotation plus the extra rotation due to the current
108
+ interaction of the user.
109
+ """
110
+ rotation = self._rotation2 * self._rotation1
111
+ return rotation.normalize()
112
+
113
+ @rotation.setter
114
+ def rotation(self, value):
115
+ print("rotation.setter called, use rotation1.setter instead")
116
+
117
+ @property
118
+ def rotation1(self):
119
+ """rotation1 records confirmed camera rotation"""
120
+ return self._rotation1
121
+
122
+ @rotation1.setter
123
+ def rotation1(self, value):
124
+ assert isinstance(value, Quaternion)
125
+ self._rotation1 = value.normalize()
126
+
127
+ @property
128
+ def rotation2(self):
129
+ """rotation2 records on going camera rotation."""
130
+ return self._rotation2
131
+
132
+ @rotation2.setter
133
+ def rotation2(self, value):
134
+ assert isinstance(value, Quaternion)
135
+ self._rotation2 = value.normalize()
136
+
137
+ @property
138
+ def auto_roll(self):
139
+ """Whether to rotate the camera automaticall to try and attempt
140
+ to keep Z up.
141
+ """
142
+ return self._auto_roll
143
+
144
+ @auto_roll.setter
145
+ def auto_roll(self, value):
146
+ self._auto_roll = bool(value)
147
+
148
+ @property
149
+ def keymap(self):
150
+ """A dictionary that maps keys to thruster directions
151
+
152
+ The keys in this dictionary are vispy key descriptions (from
153
+ vispy.keys) or characters that represent keys. These are matched
154
+ to the "key" attribute of key-press and key-release events.
155
+
156
+ The values are tuples, in which the first element specifies the
157
+ magnitude of the acceleration, using negative values for
158
+ "backward" thrust. A value of zero means to brake. The remaining
159
+ elements specify the dimension to which the acceleration should
160
+ be applied. These are 1, 2, 3 for forward/backward, left/right,
161
+ up/down, and 4, 5, 6 for pitch, yaw, roll.
162
+ """
163
+ return self._keymap
164
+
165
+ def _set_range(self, init):
166
+ """Reset the view."""
167
+ # PerspectiveCamera._set_range(self, init)
168
+ # Stop moving
169
+ self._speed *= 0.0
170
+
171
+ # Get window size (and store factor now to sync with resizing)
172
+ w, h = self._viewbox.size
173
+ w, h = float(w), float(h)
174
+
175
+ # Get range and translation for x and y
176
+ x1, y1, z1 = self._xlim[0], self._ylim[0], self._zlim[0]
177
+ x2, y2, z2 = self._xlim[1], self._ylim[1], self._zlim[1]
178
+ rx, ry, rz = (x2 - x1), (y2 - y1), (z2 - z1)
179
+
180
+ # Correct ranges for window size. Note that the window width
181
+ # influences the x and y data range, while the height influences
182
+ # the z data range.
183
+ if w / h > 1:
184
+ rx /= w / h
185
+ ry /= w / h
186
+ else:
187
+ rz /= h / w
188
+
189
+ # Do not convert to screen coordinates. This camera does not need
190
+ # to fit everything on screen, but we need to estimate the scale
191
+ # of the data in the scene.
192
+
193
+ # Set scale, depending on data range. Initial speed is such that
194
+ # the scene can be traversed in about three seconds.
195
+ self._scale_factor = max(rx, ry, rz) / 3.0
196
+
197
+ # Set initial position to a corner of the scene
198
+ margin = np.mean([rx, ry, rz]) * 0.1
199
+ self._center = x1 - margin, y1 - margin, z1 + margin
200
+
201
+ # Determine initial view direction based on flip axis
202
+ yaw = 45 * self._flip_factors[0]
203
+ pitch = -90 - 20 * self._flip_factors[2]
204
+ if self._flip_factors[1] < 0:
205
+ yaw += 90 * np.sign(self._flip_factors[0])
206
+
207
+ # Set orientation
208
+ q1 = Quaternion.create_from_axis_angle(pitch*math.pi/180, 1, 0, 0)
209
+ q2 = Quaternion.create_from_axis_angle(0*math.pi/180, 0, 1, 0)
210
+ q3 = Quaternion.create_from_axis_angle(yaw*math.pi/180, 0, 0, 1)
211
+ #
212
+ self._rotation1 = (q1 * q2 * q3).normalize()
213
+ self._rotation2 = Quaternion()
214
+
215
+ # Update
216
+ self.view_changed()
217
+
218
+ def _get_directions(self):
219
+
220
+ # Get reference points in reference coordinates
221
+ # p0 = Point(0,0,0)
222
+ pf = (0, 0, -1) # front
223
+ pr = (1, 0, 0) # right
224
+ pl = (-1, 0, 0) # left
225
+ pu = (0, 1, 0) # up
226
+
227
+ # Get total rotation
228
+ rotation = self.rotation.inverse()
229
+
230
+ # Transform to real coordinates
231
+ pf = rotation.rotate_point(pf)
232
+ pr = rotation.rotate_point(pr)
233
+ pl = rotation.rotate_point(pl)
234
+ pu = rotation.rotate_point(pu)
235
+
236
+ def _normalize(p):
237
+ L = sum(x**2 for x in p) ** 0.5
238
+ return np.array(p, 'float64') / L
239
+
240
+ pf = _normalize(pf)
241
+ pr = _normalize(pr)
242
+ pl = _normalize(pl)
243
+ pu = _normalize(pu)
244
+
245
+ return pf, pr, pl, pu
246
+
247
+ def on_timer(self, event):
248
+ """Timer event handler
249
+
250
+ Parameters
251
+ ----------
252
+ event : instance of Event
253
+ The event.
254
+ """
255
+ # Set relative speed and acceleration
256
+ rel_speed = event.dt
257
+ rel_acc = 0.1
258
+
259
+ # Get what's forward
260
+ pf, pr, pl, pu = self._get_directions()
261
+
262
+ # Increase speed through acceleration
263
+ # Note that self._speed is relative. We can balance rel_acc and
264
+ # rel_speed to get a nice smooth or direct control
265
+ self._speed += self._acc * rel_acc
266
+
267
+ # Reduce speed. Simulate resistance. Using brakes slows down faster.
268
+ # Note that the way that we reduce speed, allows for higher
269
+ # speeds if keys ar bound to higher acc values (i.e. turbo)
270
+ reduce = np.array([0.05, 0.05, 0.05, 0.1, 0.1, 0.1])
271
+ reduce[self._brake > 0] = 0.2
272
+ self._speed -= self._speed * reduce
273
+ if np.abs(self._speed).max() < 0.05:
274
+ self._speed *= 0.0
275
+
276
+ # --- Determine new position from translation speed
277
+
278
+ if self._speed[:3].any():
279
+
280
+ # Create speed vectors, use scale_factor as a reference
281
+ dv = np.array([1.0/d for d in self._flip_factors])
282
+ #
283
+ vf = pf * dv * rel_speed * self._scale_factor
284
+ vr = pr * dv * rel_speed * self._scale_factor
285
+ vu = pu * dv * rel_speed * self._scale_factor
286
+ direction = vf, vr, vu
287
+
288
+ # Set position
289
+ center_loc = np.array(self._center, dtype='float32')
290
+ center_loc += (self._speed[0] * direction[0] +
291
+ self._speed[1] * direction[1] +
292
+ self._speed[2] * direction[2])
293
+ self._center = tuple(center_loc)
294
+
295
+ # --- Determine new orientation from rotation speed
296
+
297
+ roll_angle = 0
298
+
299
+ # Calculate manual roll (from speed)
300
+ if self._speed[3:].any():
301
+ angleGain = np.array([1.0, 1.5, 1.0]) * 3 * math.pi / 180
302
+ angles = self._speed[3:] * angleGain
303
+
304
+ q1 = Quaternion.create_from_axis_angle(angles[0], -1, 0, 0)
305
+ q2 = Quaternion.create_from_axis_angle(angles[1], 0, 1, 0)
306
+ q3 = Quaternion.create_from_axis_angle(angles[2], 0, 0, -1)
307
+ q = q1 * q2 * q3
308
+ self._rotation1 = (q * self._rotation1).normalize()
309
+
310
+ # Calculate auto-roll
311
+ if self.auto_roll:
312
+ up = {'x': (1, 0, 0), 'y': (0, 1, 0), 'z': (0, 0, 1)}[self.up[1]]
313
+ up = np.array(up) * {'+': +1, '-': -1}[self.up[0]]
314
+
315
+ def angle(p1, p2):
316
+ return np.arccos(p1.dot(p2))
317
+ # au = angle(pu, (0, 0, 1))
318
+ ar = angle(pr, up)
319
+ al = angle(pl, up)
320
+ af = angle(pf, up)
321
+ # Roll angle that's off from being leveled (in unit strength)
322
+ roll_angle = math.sin(0.5*(al - ar))
323
+ # Correct for pitch
324
+ roll_angle *= abs(math.sin(af)) # abs(math.sin(au))
325
+ if abs(roll_angle) < 0.05:
326
+ roll_angle = 0
327
+ if roll_angle:
328
+ # Correct to soften the force at 90 degree angle
329
+ roll_angle = np.sign(roll_angle) * np.abs(roll_angle)**0.5
330
+ # Get correction for this iteration and apply
331
+ angle_correction = 1.0 * roll_angle * math.pi / 180
332
+ q = Quaternion.create_from_axis_angle(angle_correction,
333
+ 0, 0, 1)
334
+ self._rotation1 = (q * self._rotation1).normalize()
335
+
336
+ # Update
337
+ if self._speed.any() or roll_angle or self._update_from_mouse:
338
+ self._update_from_mouse = False
339
+ self.view_changed()
340
+
341
+ def viewbox_key_event(self, event):
342
+ """The ViewBox key event handler
343
+
344
+ Parameters
345
+ ----------
346
+ event : instance of Event
347
+ The event.
348
+ """
349
+ PerspectiveCamera.viewbox_key_event(self, event)
350
+
351
+ if event.handled or not self.interactive:
352
+ return
353
+
354
+ # Ensure the timer runs
355
+ if not self._timer.running:
356
+ self._timer.start()
357
+
358
+ if event.key in self._keymap:
359
+ val_dims = self._keymap[event.key]
360
+ val = val_dims[0]
361
+ # Brake or accelarate?
362
+ if val == 0:
363
+ vec = self._brake
364
+ val = 1
365
+ else:
366
+ vec = self._acc
367
+ # Set
368
+ if event.type == 'key_release':
369
+ val = 0
370
+ for dim in val_dims[1:]:
371
+ factor = 1.0
372
+ vec[dim-1] = val * factor
373
+ event.handled = True
374
+
375
+ def viewbox_mouse_event(self, event):
376
+ """The ViewBox mouse event handler
377
+
378
+ Parameters
379
+ ----------
380
+ event : instance of Event
381
+ The event.
382
+ """
383
+ PerspectiveCamera.viewbox_mouse_event(self, event)
384
+
385
+ if event.handled or not self.interactive:
386
+ return
387
+
388
+ if event.type == 'mouse_wheel':
389
+ if not event.mouse_event.modifiers:
390
+ # Move forward / backward
391
+ self._speed[0] += 0.5 * event.delta[1]
392
+ elif keys.SHIFT in event.mouse_event.modifiers:
393
+ # Speed
394
+ s = 1.1 ** - event.delta[1]
395
+ self.scale_factor /= s # divide instead of multiply
396
+ print('scale factor: %1.1f units/s' % self.scale_factor)
397
+ return
398
+
399
+ if event.type == 'mouse_press':
400
+ event.handled = True
401
+
402
+ if event.type == 'mouse_release':
403
+ # Reset
404
+ self._event_value = None
405
+ # Apply rotation
406
+ self._rotation1 = (self._rotation2 * self._rotation1).normalize()
407
+ self._rotation2 = Quaternion()
408
+ event.handled = True
409
+ elif not self._timer.running:
410
+ # Ensure the timer runs
411
+ self._timer.start()
412
+
413
+ if event.type == 'mouse_move':
414
+
415
+ if event.press_event is None:
416
+ return
417
+ if not event.buttons:
418
+ return
419
+
420
+ # Prepare
421
+ modifiers = event.mouse_event.modifiers
422
+ pos1 = event.mouse_event.press_event.pos
423
+ pos2 = event.mouse_event.pos
424
+ w, h = self._viewbox.size
425
+
426
+ if 1 in event.buttons and not modifiers:
427
+ # rotate
428
+
429
+ # get normalized delta values
430
+ d_az = -float(pos2[0] - pos1[0]) / w
431
+ d_el = +float(pos2[1] - pos1[1]) / h
432
+ # Apply gain
433
+ d_az *= - 0.5 * math.pi # * self._speed_rot
434
+ d_el *= + 0.5 * math.pi # * self._speed_rot
435
+ # Create temporary quaternions
436
+ q_az = Quaternion.create_from_axis_angle(d_az, 0, 1, 0)
437
+ q_el = Quaternion.create_from_axis_angle(d_el, 1, 0, 0)
438
+
439
+ # Apply to global quaternion
440
+ self._rotation2 = (q_el.normalize() * q_az).normalize()
441
+ event.handled = True
442
+
443
+ elif 2 in event.buttons and keys.CONTROL in modifiers:
444
+ # zoom --> fov
445
+ if self._event_value is None:
446
+ self._event_value = self._fov
447
+ p1 = np.array(event.press_event.pos)[:2]
448
+ p2 = np.array(event.pos)[:2]
449
+ p1c = event.map_to_canvas(p1)[:2]
450
+ p2c = event.map_to_canvas(p2)[:2]
451
+ d = p2c - p1c
452
+ fov = self._event_value * math.exp(-0.01*d[1])
453
+ self._fov = min(90.0, max(10, fov))
454
+ event.handled = True
455
+
456
+ # Make transform be updated on the next timer tick.
457
+ # By doing it at timer tick, we avoid shaky behavior
458
+ self._update_from_mouse = True
459
+
460
+ def _update_projection_transform(self, fx, fy):
461
+ PerspectiveCamera._update_projection_transform(self, fx, fy)
462
+
463
+ # Turn our internal quaternion representation into rotation
464
+ # of our transform
465
+
466
+ axis_angle = self.rotation.get_axis_angle()
467
+ angle = axis_angle[0] * 180 / math.pi
468
+
469
+ tr = self.transform
470
+ tr.reset()
471
+ #
472
+ tr.rotate(-angle, axis_angle[1:])
473
+ tr.scale([1.0/a for a in self._flip_factors])
474
+ tr.translate(self._center)
@@ -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
+ from __future__ import division
5
+
6
+ import numpy as np
7
+
8
+ from .panzoom import PanZoomCamera
9
+ from ...visuals.transforms.nonlinear import (MagnifyTransform,
10
+ Magnify1DTransform)
11
+ from ...app import Timer
12
+
13
+
14
+ class MagnifyCamera(PanZoomCamera):
15
+ """Camera implementing a MagnifyTransform combined with PanZoomCamera.
16
+
17
+ Parameters
18
+ ----------
19
+ size_factor : float
20
+ The size factor to use.
21
+ radius_ratio : float
22
+ The radius ratio to use.
23
+ **kwargs : dict
24
+ Keyword arguments to pass to `PanZoomCamera` and create a transform.
25
+
26
+ Notes
27
+ -----
28
+ This Camera uses the mouse cursor position to set the center position of
29
+ the MagnifyTransform, and uses mouse wheel events to adjust the
30
+ magnification factor.
31
+
32
+ At high magnification, very small mouse movements can result in large
33
+ changes, so we use a timer to animate transitions in the transform
34
+ properties.
35
+
36
+ The camera also adjusts the size of its "lens" area when the view is
37
+ resized.
38
+ """
39
+
40
+ transform_class = MagnifyTransform
41
+
42
+ def __init__(self, size_factor=0.25, radius_ratio=0.9, **kwargs):
43
+ # what fraction of the view width to use for radius
44
+ self.size_factor = size_factor
45
+
46
+ # ratio of inner to outer lens radius
47
+ self.radius_ratio = radius_ratio
48
+
49
+ # Extract kwargs for panzoom
50
+ camkwargs = {}
51
+ for key in ('parent', 'name', 'rect', 'aspect'):
52
+ if key in kwargs:
53
+ camkwargs[key] = kwargs.pop(key)
54
+
55
+ # Create the mag transform - kwrds go here
56
+ self.mag = self.transform_class(**kwargs)
57
+
58
+ # for handling smooth transitions
59
+ self.mag_target = self.mag.mag
60
+ self.mag._mag = self.mag_target
61
+ self.mouse_pos = None
62
+ self.timer = Timer(interval=0.016, connect=self.on_timer)
63
+
64
+ super(MagnifyCamera, self).__init__(**camkwargs)
65
+
66
+ # This tells the camera to insert the magnification transform at the
67
+ # beginning of the transform it applies to the scene. This is the
68
+ # correct place for the mag transform because:
69
+ # 1. We want it to apply to everything inside the scene, and not to
70
+ # the ViewBox itself or anything outside of the ViewBox.
71
+ # 2. We do _not_ want the pan/zoom transforms applied first, because
72
+ # the scale factors implemented there should not change the shape
73
+ # of the lens.
74
+ self.pre_transform = self.mag
75
+
76
+ def _viewbox_set(self, viewbox):
77
+ PanZoomCamera._viewbox_set(self, viewbox)
78
+
79
+ def _viewbox_unset(self, viewbox):
80
+ PanZoomCamera._viewbox_unset(self, viewbox)
81
+ self.timer.stop()
82
+
83
+ def viewbox_mouse_event(self, event):
84
+ """The ViewBox mouse event handler
85
+
86
+ Parameters
87
+ ----------
88
+ event : instance of Event
89
+ The mouse event.
90
+ """
91
+ # When the attached ViewBox reseives a mouse event, it is sent to the
92
+ # camera here.
93
+
94
+ self.mouse_pos = event.pos[:2]
95
+ if event.type == 'mouse_wheel':
96
+ # wheel rolled; adjust the magnification factor and hide the
97
+ # event from the superclass
98
+ m = self.mag_target
99
+ m *= 1.2 ** event.delta[1]
100
+ m = m if m > 1 else 1
101
+ self.mag_target = m
102
+ else:
103
+ # send everything _except_ wheel events to the superclass
104
+ super(MagnifyCamera, self).viewbox_mouse_event(event)
105
+
106
+ # start the timer to smoothly modify the transform properties.
107
+ if not self.timer.running:
108
+ self.timer.start()
109
+
110
+ self._update_transform()
111
+
112
+ def on_timer(self, event=None):
113
+ """Timer event handler
114
+
115
+ Parameters
116
+ ----------
117
+ event : instance of Event
118
+ The timer event.
119
+ """
120
+ # Smoothly update center and magnification properties of the transform
121
+ k = np.clip(100. / self.mag.mag, 10, 100)
122
+ s = 10**(-k * event.dt)
123
+
124
+ c = np.array(self.mag.center)
125
+ c1 = c * s + self.mouse_pos * (1-s)
126
+
127
+ m = self.mag.mag * s + self.mag_target * (1-s)
128
+
129
+ # If changes are very small, then it is safe to stop the timer.
130
+ if (np.all(np.abs((c - c1) / c1) < 1e-5) and
131
+ (np.abs(np.log(m / self.mag.mag)) < 1e-3)):
132
+ self.timer.stop()
133
+
134
+ self.mag.center = c1
135
+ self.mag.mag = m
136
+
137
+ self._update_transform()
138
+
139
+ def viewbox_resize_event(self, event):
140
+ """The ViewBox resize event handler
141
+
142
+ Parameters
143
+ ----------
144
+ event : instance of Event
145
+ The viewbox resize event.
146
+ """
147
+ PanZoomCamera.viewbox_resize_event(self, event)
148
+ self.view_changed()
149
+
150
+ def view_changed(self):
151
+ # make sure radii are updated when a view is attached.
152
+ # when the view resizes, we change the lens radii to match.
153
+ if self._viewbox is not None:
154
+ vbs = self._viewbox.size
155
+ r = min(vbs) * self.size_factor
156
+ self.mag.radii = r * self.radius_ratio, r
157
+
158
+ PanZoomCamera.view_changed(self)
159
+
160
+
161
+ class Magnify1DCamera(MagnifyCamera):
162
+ transform_class = Magnify1DTransform
163
+ __doc__ = MagnifyCamera.__doc__