vispy 0.15.0__cp313-cp313-win_amd64.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.cp313-win_amd64.pyd +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 +5 -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
vispy/io/image.py ADDED
@@ -0,0 +1,231 @@
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
+ # Author: Luke Campagnola
7
+ # -----------------------------------------------------------------------------
8
+
9
+
10
+ import struct
11
+ import zlib
12
+ import numpy as np
13
+
14
+
15
+ def _make_png(data, level=6):
16
+ """Convert numpy array to PNG byte array.
17
+
18
+ Parameters
19
+ ----------
20
+ data : numpy.ndarray
21
+ Data must be (H, W, 3 | 4) with dtype = np.ubyte (np.uint8)
22
+ level : int
23
+ https://docs.python.org/2/library/zlib.html#zlib.compress
24
+ An integer from 0 to 9 controlling the level of compression:
25
+
26
+ * 1 is fastest and produces the least compression,
27
+ * 9 is slowest and produces the most.
28
+ * 0 is no compression.
29
+
30
+ The default value is 6.
31
+
32
+ Returns
33
+ -------
34
+ png : array
35
+ PNG formatted array
36
+ """
37
+ # Eventually we might want to use ext/png.py for this, but this
38
+ # routine *should* be faster b/c it's specialized for our use case
39
+
40
+ def mkchunk(data, name):
41
+ if isinstance(data, np.ndarray):
42
+ size = data.nbytes
43
+ else:
44
+ size = len(data)
45
+ chunk = np.empty(size + 12, dtype=np.ubyte)
46
+ chunk.data[0:4] = np.array(size, '>u4').tobytes()
47
+ chunk.data[4:8] = name.encode('ASCII')
48
+ chunk.data[8:8 + size] = data
49
+ # and-ing may not be necessary, but is done for safety:
50
+ # https://docs.python.org/3/library/zlib.html#zlib.crc32
51
+ chunk.data[-4:] = np.array(zlib.crc32(chunk[4:-4]) & 0xffffffff,
52
+ '>u4').tobytes()
53
+ return chunk
54
+
55
+ if data.dtype != np.ubyte:
56
+ raise TypeError('data.dtype must be np.ubyte (np.uint8)')
57
+
58
+ dim = data.shape[2] # Dimension
59
+ if dim not in (3, 4):
60
+ raise TypeError('data.shape[2] must be in (3, 4)')
61
+
62
+ # www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IHDR
63
+ if dim == 4:
64
+ ctyp = 0b0110 # RGBA
65
+ else:
66
+ ctyp = 0b0010 # RGB
67
+
68
+ # www.libpng.org/pub/png/spec/1.2/PNG-Structure.html
69
+ header = b'\x89PNG\x0d\x0a\x1a\x0a' # header
70
+
71
+ h, w = data.shape[:2]
72
+ depth = data.itemsize * 8
73
+ ihdr = struct.pack('!IIBBBBB', w, h, depth, ctyp, 0, 0, 0)
74
+ c1 = mkchunk(ihdr, 'IHDR')
75
+
76
+ # www.libpng.org/pub/png/spec/1.2/PNG-Chunks.html#C.IDAT
77
+ # insert filter byte at each scanline
78
+ idat = np.empty((h, w * dim + 1), dtype=np.ubyte)
79
+ idat[:, 1:] = data.reshape(h, w * dim)
80
+ idat[:, 0] = 0
81
+
82
+ comp_data = zlib.compress(idat, level)
83
+ c2 = mkchunk(comp_data, 'IDAT')
84
+ c3 = mkchunk(np.empty((0,), dtype=np.ubyte), 'IEND')
85
+
86
+ # concatenate
87
+ lh = len(header)
88
+ png = np.empty(lh + c1.nbytes + c2.nbytes + c3.nbytes, dtype=np.ubyte)
89
+ png.data[:lh] = header
90
+ p = lh
91
+
92
+ for chunk in (c1, c2, c3):
93
+ png[p:p + len(chunk)] = chunk
94
+ p += chunk.nbytes
95
+
96
+ return png
97
+
98
+
99
+ def read_png(filename):
100
+ """Read a PNG file to RGB8 or RGBA8
101
+ Requires Pillow.
102
+
103
+ Parameters
104
+ ----------
105
+ filename : str
106
+ File to read.
107
+
108
+ Returns
109
+ -------
110
+ data : array
111
+ Image data.
112
+
113
+ See also
114
+ --------
115
+ write_png, imread, imsave
116
+ """
117
+ try:
118
+ from PIL import Image
119
+ x = Image.open(filename)
120
+ try:
121
+ y = np.asarray(x)
122
+ y = np.array([yy for yy in y], np.uint8)
123
+ finally:
124
+ x.close()
125
+ return y
126
+ except ImportError:
127
+ raise RuntimeError("read_png requires the Pillow package.")
128
+
129
+
130
+ def write_png(filename, data):
131
+ """Write a PNG file
132
+
133
+ Unlike imsave, this requires no external dependencies.
134
+
135
+ Parameters
136
+ ----------
137
+ filename : str
138
+ File to save to.
139
+ data : array
140
+ Image data.
141
+
142
+ See also
143
+ --------
144
+ read_png, imread, imsave
145
+ """
146
+ data = np.asarray(data)
147
+ if not data.ndim == 3 and data.shape[-1] in (3, 4):
148
+ raise ValueError('data must be a 3D array with last dimension 3 or 4')
149
+ with open(filename, 'wb') as f:
150
+ f.write(_make_png(data)) # Save array with make_png
151
+
152
+
153
+ def imread(filename, format=None):
154
+ """Read image data from disk
155
+
156
+ Requires imageio or PIL.
157
+
158
+ Parameters
159
+ ----------
160
+ filename : str
161
+ Filename to read.
162
+ format : str | None
163
+ Format of the file. If None, it will be inferred from the filename.
164
+
165
+ Returns
166
+ -------
167
+ data : array
168
+ Image data.
169
+
170
+ See also
171
+ --------
172
+ imsave, read_png, write_png
173
+ """
174
+ imageio, PIL = _check_img_lib()
175
+ if imageio is not None:
176
+ return imageio.imread(filename, format)
177
+ elif PIL is not None:
178
+ im = PIL.Image.open(filename)
179
+ if im.mode == 'P':
180
+ im = im.convert()
181
+ # Make numpy array
182
+ a = np.asarray(im)
183
+ if len(a.shape) == 0:
184
+ raise MemoryError("Too little memory to convert PIL image to "
185
+ "array")
186
+ return a
187
+ else:
188
+ raise RuntimeError("imread requires the imageio or PIL package.")
189
+
190
+
191
+ def imsave(filename, im, format=None):
192
+ """Save image data to disk
193
+
194
+ Requires imageio or PIL.
195
+
196
+ Parameters
197
+ ----------
198
+ filename : str
199
+ Filename to write.
200
+ im : array
201
+ Image data.
202
+ format : str | None
203
+ Format of the file. If None, it will be inferred from the filename.
204
+
205
+ See also
206
+ --------
207
+ imread, read_png, write_png
208
+ """
209
+ # Import imageio or PIL
210
+ imageio, PIL = _check_img_lib()
211
+ if imageio is not None:
212
+ return imageio.imsave(filename, im, format)
213
+ elif PIL is not None:
214
+ pim = PIL.Image.fromarray(im)
215
+ pim.save(filename, format)
216
+ else:
217
+ raise RuntimeError("imsave requires the imageio or PIL package.")
218
+
219
+
220
+ def _check_img_lib():
221
+ """Utility to search for imageio or PIL"""
222
+ # Import imageio or PIL
223
+ imageio = PIL = None
224
+ try:
225
+ import imageio
226
+ except ImportError:
227
+ try:
228
+ import PIL.Image
229
+ except ImportError:
230
+ pass
231
+ return imageio, PIL
vispy/io/mesh.py ADDED
@@ -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
+ """Reading and writing of data like images and meshes."""
6
+
7
+ import os
8
+ from os import path as op
9
+
10
+ from .wavefront import WavefrontReader, WavefrontWriter
11
+ from .stl import load_stl
12
+
13
+
14
+ def read_mesh(fname):
15
+ """Read mesh data from file.
16
+
17
+ Parameters
18
+ ----------
19
+ fname : str
20
+ File name to read. Format will be inferred from the filename.
21
+ Currently only '.obj' and '.obj.gz' are supported.
22
+
23
+ Returns
24
+ -------
25
+ vertices : array
26
+ Vertices.
27
+ faces : array | None
28
+ Triangle face definitions.
29
+ normals : array
30
+ Normals for the mesh.
31
+ texcoords : array | None
32
+ Texture coordinates.
33
+ """
34
+ # Check format
35
+ fmt = op.splitext(fname)[1].lower()
36
+ if fmt == '.gz':
37
+ fmt = op.splitext(op.splitext(fname)[0])[1].lower()
38
+
39
+ if fmt in ('.obj'):
40
+ return WavefrontReader.read(fname)
41
+ elif fmt in ('.stl'):
42
+ file_obj = open(fname, mode='rb')
43
+ mesh = load_stl(file_obj)
44
+ vertices = mesh['vertices']
45
+ faces = mesh['faces']
46
+ normals = mesh['face_normals']
47
+ texcoords = None
48
+ return vertices, faces, normals, texcoords
49
+ else:
50
+ try:
51
+ import meshio
52
+ except ImportError:
53
+ raise ValueError('read_mesh does not understand format %s.' % fmt)
54
+
55
+ try:
56
+ mesh = meshio.read(fname)
57
+ except meshio.ReadError:
58
+ raise ValueError('read_mesh does not understand format %s.' % fmt)
59
+
60
+ triangles = mesh.get_cells_type("triangle")
61
+ if len(triangles) == 0:
62
+ raise ValueError('mesh file does not contain triangles.')
63
+
64
+ return mesh.points, triangles, None, None
65
+
66
+
67
+ def write_mesh(fname, vertices, faces, normals, texcoords, name='',
68
+ format=None, overwrite=False, reshape_faces=True):
69
+ """Write mesh data to file.
70
+
71
+ Parameters
72
+ ----------
73
+ fname : str
74
+ Filename to write. Must end with ".obj" or ".gz".
75
+ vertices : array
76
+ Vertices.
77
+ faces : array | None
78
+ Triangle face definitions.
79
+ normals : array
80
+ Normals for the mesh.
81
+ texcoords : array | None
82
+ Texture coordinates.
83
+ name : str
84
+ Name of the object.
85
+ format : str
86
+ Currently only "obj" is supported.
87
+ overwrite : bool
88
+ If the file exists, overwrite it.
89
+ reshape_faces : bool
90
+ Reshape the `faces` array to (Nf, 3). Set to `False`
91
+ if you need to write a mesh with non triangular faces.
92
+ """
93
+ # Check file
94
+ if op.isfile(fname) and not overwrite:
95
+ raise IOError('file "%s" exists, use overwrite=True' % fname)
96
+
97
+ if format is None:
98
+ format = os.path.splitext(fname)[1][1:]
99
+
100
+ # Check format
101
+ if format == 'obj':
102
+ WavefrontWriter.write(fname, vertices, faces,
103
+ normals, texcoords, name, reshape_faces)
104
+ return
105
+
106
+ try:
107
+ import meshio
108
+ except ImportError:
109
+ raise ValueError('write_mesh does not understand format %s.' % format)
110
+
111
+ cell_data = {}
112
+ if normals is not None:
113
+ cell_data["normals"] = [normals]
114
+ if texcoords is not None:
115
+ cell_data["texcoords"] = [texcoords]
116
+
117
+ mesh = meshio.Mesh(vertices, [("triangle", faces)], cell_data=cell_data)
118
+
119
+ try:
120
+ mesh.write(fname, file_format=format)
121
+ except meshio.WriteError:
122
+ raise ValueError('write_mesh does not understand format %s.' % format)
vispy/io/stl.py ADDED
@@ -0,0 +1,167 @@
1
+ # -*- coding: utf-8 -*-
2
+ # Copyright (c) 2015 Michael Dawson-Haggerty
3
+ # Distributed under the MIT License.
4
+ # Copied from the trimesh project.
5
+ # See https://github.com/mikedh/trimesh for more information.
6
+ # See https://github.com/mikedh/trimesh/blob/master/LICENSE.md for
7
+ # the license.
8
+
9
+ import numpy as np
10
+
11
+
12
+ class HeaderError(Exception):
13
+ # the exception raised if an STL file object doesn't match its header
14
+ pass
15
+
16
+
17
+ # define a numpy datatype for the data section of a binary STL file
18
+ _stl_dtype = np.dtype([('normals', np.float32, (3)),
19
+ ('vertices', np.float32, (3, 3)),
20
+ ('attributes', np.uint16)])
21
+ # define a numpy datatype for the header of a binary STL file
22
+ _stl_dtype_header = np.dtype([('header', np.void, 80),
23
+ ('face_count', np.int32)])
24
+
25
+
26
+ def load_stl(file_obj, file_type=None):
27
+ """
28
+ Load an STL file from a file object.
29
+
30
+ Parameters
31
+ ----------
32
+ file_obj: open file- like object
33
+ file_type: not used
34
+
35
+ Returns
36
+ -------
37
+ loaded: kwargs for a Trimesh constructor with keys:
38
+ vertices: (n,3) float, vertices
39
+ faces: (m,3) int, indexes of vertices
40
+ face_normals: (m,3) float, normal vector of each face
41
+ """
42
+ # save start of file obj
43
+ file_pos = file_obj.tell()
44
+ try:
45
+ # check the file for a header which matches the file length
46
+ # if that is true, it is almost certainly a binary STL file
47
+ # if the header doesn't match the file length a HeaderError will be
48
+ # raised
49
+ return load_stl_binary(file_obj)
50
+ except HeaderError:
51
+ # move the file back to where it was initially
52
+ file_obj.seek(file_pos)
53
+ # try to load the file as an ASCII STL
54
+ # if the header doesn't match the file length a HeaderError will be
55
+ # raised
56
+ return load_stl_ascii(file_obj)
57
+
58
+
59
+ def load_stl_binary(file_obj):
60
+ """
61
+ Load a binary STL file from a file object.
62
+
63
+ Parameters
64
+ ----------
65
+ file_obj: open file- like object
66
+
67
+ Returns
68
+ -------
69
+ loaded: kwargs for a Trimesh constructor with keys:
70
+ vertices: (n,3) float, vertices
71
+ faces: (m,3) int, indexes of vertices
72
+ face_normals: (m,3) float, normal vector of each face
73
+ """
74
+ # the header is always 84 bytes long, we just reference the dtype.itemsize
75
+ # to be explicit about where that magical number comes from
76
+ header_length = _stl_dtype_header.itemsize
77
+ header_data = file_obj.read(header_length)
78
+ if len(header_data) < header_length:
79
+ raise HeaderError('Binary STL file not long enough to contain header!')
80
+
81
+ header = np.fromstring(header_data, dtype=_stl_dtype_header)
82
+
83
+ # now we check the length from the header versus the length of the file
84
+ # data_start should always be position 84, but hard coding that felt ugly
85
+ data_start = file_obj.tell()
86
+ # this seeks to the end of the file
87
+ # position 0, relative to the end of the file 'whence=2'
88
+ file_obj.seek(0, 2)
89
+ # we save the location of the end of the file and seek back to where we
90
+ # started from
91
+ data_end = file_obj.tell()
92
+ file_obj.seek(data_start)
93
+
94
+ # the binary format has a rigidly defined structure, and if the length
95
+ # of the file doesn't match the header, the loaded version is almost
96
+ # certainly going to be garbage.
97
+ len_data = data_end - data_start
98
+ len_expected = header['face_count'] * _stl_dtype.itemsize
99
+
100
+ # this check is to see if this really is a binary STL file.
101
+ # if we don't do this and try to load a file that isn't structured properly
102
+ # we will be producing garbage or crashing hard
103
+ # so it's much better to raise an exception here.
104
+ if len_data != len_expected:
105
+ raise HeaderError('Binary STL has incorrect length in header!')
106
+
107
+ # all of our vertices will be loaded in order due to the STL format,
108
+ # so faces are just sequential indices reshaped.
109
+ faces = np.arange(header['face_count'] * 3).reshape((-1, 3))
110
+ blob = np.fromstring(file_obj.read(), dtype=_stl_dtype)
111
+
112
+ result = {'vertices': blob['vertices'].reshape((-1, 3)),
113
+ 'face_normals': blob['normals'].reshape((-1, 3)),
114
+ 'faces': faces}
115
+ return result
116
+
117
+
118
+ def load_stl_ascii(file_obj):
119
+ """
120
+ Load an ASCII STL file from a file object.
121
+
122
+ Parameters
123
+ ----------
124
+ file_obj: open file- like object
125
+
126
+ Returns
127
+ -------
128
+ loaded: kwargs for a Trimesh constructor with keys:
129
+ vertices: (n,3) float, vertices
130
+ faces: (m,3) int, indexes of vertices
131
+ face_normals: (m,3) float, normal vector of each face
132
+ """
133
+ # header (not used by this function)
134
+ file_obj.readline()
135
+
136
+ text = file_obj.read()
137
+ if hasattr(text, 'decode'):
138
+ text = text.decode('utf-8')
139
+ text = text.lower().split('endsolid')[0]
140
+ blob = np.array(text.split())
141
+
142
+ # there are 21 'words' in each face
143
+ face_len = 21
144
+ face_count = len(blob) / face_len
145
+ if (len(blob) % face_len) != 0:
146
+ raise HeaderError('Incorrect number of values in STL file!')
147
+
148
+ face_count = int(face_count)
149
+ # this offset is to be added to a fixed set of indices that is tiled
150
+ offset = face_len * np.arange(face_count).reshape((-1, 1))
151
+ normal_index = np.tile([2, 3, 4], (face_count, 1)) + offset
152
+ vertex_index = np.tile(
153
+ [8, 9, 10, 12, 13, 14, 16, 17, 18], (face_count, 1)) + offset
154
+
155
+ # faces are groups of three sequential vertices, as vertices are not
156
+ # references
157
+ faces = np.arange(face_count * 3).reshape((-1, 3))
158
+ face_normals = blob[normal_index].astype(np.float64)
159
+ vertices = blob[vertex_index.reshape((-1, 3))].astype(np.float64)
160
+
161
+ return {'vertices': vertices,
162
+ 'faces': faces,
163
+ 'face_normals': face_normals}
164
+
165
+
166
+ _stl_loaders = {'stl': load_stl,
167
+ 'stl_ascii': load_stl}
File without changes
@@ -0,0 +1,47 @@
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
+ import numpy as np
5
+ from numpy.testing import assert_array_equal, assert_allclose
6
+ from os import path as op
7
+ import warnings
8
+
9
+ from vispy.io import load_crate, imsave, imread, read_png, write_png
10
+ from vispy.testing import requires_img_lib, run_tests_if_main
11
+ from vispy.util import _TempDir
12
+
13
+ temp_dir = _TempDir()
14
+
15
+
16
+ def test_make_png():
17
+ """Test to ensure that make_png functions correctly."""
18
+ # Save random RGBA and RGB arrays onto disk as PNGs using make_png.
19
+ # Read them back with an image library and check whether the array
20
+ # saved is equal to the array read.
21
+
22
+ # Create random RGBA array as type ubyte
23
+ rgba_save = np.random.randint(256, size=(100, 100, 4)).astype(np.ubyte)
24
+ # Get rid of the alpha for RGB
25
+ rgb_save = rgba_save[:, :, :3]
26
+ # Output file should be in temp
27
+ png_out = op.join(temp_dir, 'random.png')
28
+
29
+ # write_png implicitly tests _make_png
30
+ for rgb_a in (rgba_save, rgb_save):
31
+ write_png(png_out, rgb_a)
32
+ rgb_a_read = read_png(png_out)
33
+ assert_array_equal(rgb_a, rgb_a_read)
34
+
35
+
36
+ @requires_img_lib()
37
+ def test_read_write_image():
38
+ """Test reading and writing of images"""
39
+ fname = op.join(temp_dir, 'out.png')
40
+ im1 = load_crate()
41
+ imsave(fname, im1, format='png')
42
+ with warnings.catch_warnings(record=True): # PIL unclosed file
43
+ im2 = imread(fname)
44
+ assert_allclose(im1, im2)
45
+
46
+
47
+ run_tests_if_main()
@@ -0,0 +1,121 @@
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
+ import numpy as np
5
+ from os import path as op
6
+ from numpy.testing import assert_allclose, assert_array_equal
7
+
8
+ from vispy.io import write_mesh, read_mesh, load_data_file
9
+ from vispy.geometry import _fast_cross_3d
10
+ from vispy.util import _TempDir
11
+ from vispy.testing import (run_tests_if_main, assert_equal, assert_raises,
12
+ requires_ssl)
13
+
14
+ temp_dir = _TempDir()
15
+
16
+
17
+ @requires_ssl()
18
+ def test_wavefront():
19
+ """Test wavefront reader"""
20
+ fname_mesh = load_data_file('orig/triceratops.obj.gz')
21
+ fname_out = op.join(temp_dir, 'temp.obj')
22
+ mesh1 = read_mesh(fname_mesh)
23
+ assert_raises(IOError, read_mesh, 'foo.obj')
24
+ assert_raises(ValueError, read_mesh, op.abspath(__file__))
25
+ assert_raises(ValueError, write_mesh, fname_out, *mesh1, format='foo')
26
+ write_mesh(fname_out, mesh1[0], mesh1[1], mesh1[2], mesh1[3])
27
+ assert_raises(IOError, write_mesh, fname_out, *mesh1)
28
+ write_mesh(fname_out, *mesh1, overwrite=True)
29
+ mesh2 = read_mesh(fname_out)
30
+ assert_equal(len(mesh1), len(mesh2))
31
+ for m1, m2 in zip(mesh1, mesh2):
32
+ if m1 is None:
33
+ assert_equal(m2, None)
34
+ else:
35
+ assert_allclose(m1, m2, rtol=1e-5)
36
+ # test our efficient normal calculation routine
37
+ assert_allclose(mesh1[2], _slow_calculate_normals(mesh1[0], mesh1[1]),
38
+ rtol=1e-7, atol=1e-7)
39
+
40
+
41
+ def test_wavefront_non_triangular():
42
+ """Test wavefront writing with non-triangular faces"""
43
+ vertices = np.array([[0.5, 1.375, 0.],
44
+ [0.5, 0.625, 0.],
45
+ [3.25, 1., 0.],
46
+ [1., 0.375, 0.],
47
+ [2., 0.375, 0.],
48
+ [1.5, 0.625, 0.],
49
+ [1.5, 1.375, 0.],
50
+ [1., 1.625, 0.],
51
+ [2., 1.625, 0.]])
52
+
53
+ faces = np.array([[1, 0, 7, 6, 5, 3],
54
+ [4, 5, 6, 8, 2]], dtype=object)
55
+ fname_out = op.join(temp_dir, 'temp.obj')
56
+ write_mesh(fname_out, vertices=vertices,
57
+ faces=faces, normals=None,
58
+ texcoords=None, overwrite=True,
59
+ reshape_faces=False)
60
+ assert_raises(RuntimeError, read_mesh, fname_out)
61
+ with open(fname_out, 'r+') as out_file:
62
+ lines = out_file.readlines()
63
+ assert lines[-1].startswith('f 5 6 7 9 3')
64
+ assert lines[-2].startswith('f 2 1 8 7 6 4')
65
+
66
+
67
+ def test_meshio():
68
+ """Test meshio i/o"""
69
+ vertices = np.array([[0.0, 0.0, 0.0],
70
+ [1.0, 0.0, 0.],
71
+ [-.0, 1.0, 0.],
72
+ [1.0, 1.0, 0.]])
73
+
74
+ faces = np.array([[0, 1, 3],
75
+ [1, 2, 3]])
76
+ fname_out = op.join(temp_dir, 'temp.vtk')
77
+ write_mesh(fname_out, vertices=vertices,
78
+ faces=faces, normals=None,
79
+ texcoords=None, overwrite=True,
80
+ reshape_faces=False)
81
+ out_vertices, out_faces, _, _ = read_mesh(fname_out)
82
+
83
+ assert np.all(np.abs(out_vertices - vertices) < 1.0e-14)
84
+ assert np.all(out_faces == faces)
85
+
86
+
87
+ def _slow_calculate_normals(rr, tris):
88
+ """Efficiently compute vertex normals for triangulated surface"""
89
+ # first, compute triangle normals
90
+ rr = rr.astype(np.float64)
91
+ r1 = rr[tris[:, 0], :]
92
+ r2 = rr[tris[:, 1], :]
93
+ r3 = rr[tris[:, 2], :]
94
+ tri_nn = np.cross((r2 - r1), (r3 - r1))
95
+
96
+ # Triangle normals and areas
97
+ size = np.sqrt(np.sum(tri_nn * tri_nn, axis=1))
98
+ zidx = np.where(size == 0)[0]
99
+ size[zidx] = 1.0 # prevent ugly divide-by-zero
100
+ tri_nn /= size[:, np.newaxis]
101
+
102
+ # accumulate the normals
103
+ nn = np.zeros((len(rr), 3))
104
+ for p, verts in enumerate(tris):
105
+ nn[verts] += tri_nn[p, :]
106
+ size = np.sqrt(np.sum(nn * nn, axis=1))
107
+ size[size == 0] = 1.0 # prevent ugly divide-by-zero
108
+ nn /= size[:, np.newaxis]
109
+ return nn
110
+
111
+
112
+ def test_huge_cross():
113
+ """Test cross product with lots of elements"""
114
+ x = np.random.rand(100000, 3)
115
+ y = np.random.rand(1, 3)
116
+ z = np.cross(x, y)
117
+ zz = _fast_cross_3d(x, y)
118
+ assert_array_equal(z, zz)
119
+
120
+
121
+ run_tests_if_main()