vispy 0.14.0__cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl

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

Potentially problematic release.


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

Files changed (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-312-aarch64-linux-gnu.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 +6 -0
  519. vispy-0.14.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,698 @@
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
+ import numpy as np
6
+
7
+
8
+ def _fix_colors(colors):
9
+ colors = np.asarray(colors)
10
+ if colors.ndim not in (2, 3):
11
+ raise ValueError('colors must have 2 or 3 dimensions')
12
+ if colors.shape[-1] not in (3, 4):
13
+ raise ValueError('colors must have 3 or 4 elements')
14
+ if colors.shape[-1] == 3:
15
+ pad = np.ones((len(colors), 1), colors.dtype)
16
+ if colors.ndim == 3:
17
+ pad = pad[:, :, np.newaxis]
18
+ colors = np.concatenate((colors, pad), axis=-1)
19
+ return colors
20
+
21
+
22
+ def _compute_face_normals(vertices):
23
+ if vertices.shape[1:] != (3, 3):
24
+ raise ValueError("Expected (N, 3, 3) array of vertices repeated on"
25
+ f" the triangle corners, got {vertices.shape}.")
26
+ edges1 = vertices[:, 1] - vertices[:, 0]
27
+ edges2 = vertices[:, 2] - vertices[:, 0]
28
+ return np.cross(edges1, edges2)
29
+
30
+
31
+ def _repeat_face_normals_on_corners(normals):
32
+ if normals.shape[1:] != (3,):
33
+ raise ValueError("Expected (F, 3) array of face normals, got"
34
+ f" {normals.shape}.")
35
+ n_corners_in_face = 3
36
+ new_shape = (normals.shape[0], n_corners_in_face, normals.shape[1])
37
+ return np.repeat(normals, n_corners_in_face, axis=0).reshape(new_shape)
38
+
39
+
40
+ def _compute_vertex_normals(face_normals, faces, vertices):
41
+ if face_normals.shape[1:] != (3,):
42
+ raise ValueError("Expected (F, 3) array of face normals, got"
43
+ f" {face_normals.shape}.")
44
+ if faces.shape[1:] != (3,):
45
+ raise ValueError("Expected (F, 3) array of face vertex indices, got"
46
+ f" {faces.shape}.")
47
+ if vertices.shape[1:] != (3,):
48
+ raise ValueError("Expected (N, 3) array of vertices, got"
49
+ f" {vertices.shape}.")
50
+
51
+ vertex_normals = np.zeros_like(vertices)
52
+ n_corners_in_triangle = 3
53
+ face_normals_repeated_on_corners = np.repeat(face_normals,
54
+ n_corners_in_triangle,
55
+ axis=0)
56
+ # NOTE: The next line is equivalent to
57
+ #
58
+ # vertex_normals[self._faces.ravel()] += face_normals_repeated_on_corners
59
+ #
60
+ # except that it accumulates the values from the right hand side at
61
+ # repeated indices on the left hand side, instead of overwritting them,
62
+ # like in the above.
63
+ np.add.at(vertex_normals, faces.ravel(), face_normals_repeated_on_corners)
64
+
65
+ norms = np.sqrt((vertex_normals**2).sum(axis=1))
66
+ nonzero_norms = norms > 0
67
+ vertex_normals[nonzero_norms] /= norms[nonzero_norms][:, None]
68
+
69
+ return vertex_normals
70
+
71
+
72
+ class MeshData(object):
73
+ """
74
+ Class for storing and operating on 3D mesh data.
75
+
76
+ Parameters
77
+ ----------
78
+ vertices : ndarray, shape (Nv, 3)
79
+ Vertex coordinates. If faces is not specified, then this will
80
+ instead be interpreted as (Nf, 3, 3) array of coordinates.
81
+ faces : ndarray, shape (Nf, 3)
82
+ Indices into the vertex array.
83
+ edges : None
84
+ [not available yet]
85
+ vertex_colors : ndarray, shape (Nv, 4)
86
+ Vertex colors. If faces is not specified, this will be
87
+ interpreted as (Nf, 3, 4) array of colors.
88
+ face_colors : ndarray, shape (Nf, 4)
89
+ Face colors.
90
+ vertex_values : ndarray, shape (Nv,)
91
+ Vertex values.
92
+
93
+ Notes
94
+ -----
95
+ All arguments are optional.
96
+
97
+ The object may contain:
98
+
99
+ - list of vertex locations
100
+ - list of edges
101
+ - list of triangles
102
+ - colors per vertex, edge, or tri
103
+ - normals per vertex or tri
104
+
105
+ This class handles conversion between the standard
106
+ [list of vertices, list of faces] format (suitable for use with
107
+ glDrawElements) and 'indexed' [list of vertices] format (suitable
108
+ for use with glDrawArrays). It will automatically compute face normal
109
+ vectors as well as averaged vertex normal vectors.
110
+
111
+ The class attempts to be as efficient as possible in caching conversion
112
+ results and avoiding unnecessary conversions.
113
+ """
114
+
115
+ def __init__(self, vertices=None, faces=None, edges=None,
116
+ vertex_colors=None, face_colors=None, vertex_values=None):
117
+ self._vertices = None # (Nv,3) array of vertex coordinates
118
+ self._vertices_indexed_by_faces = None # (Nf, 3, 3) vertex coordinates
119
+ self._vertices_indexed_by_edges = None # (Ne, 2, 3) vertex coordinates
120
+
121
+ # mappings between vertices, faces, and edges
122
+ self._faces = None # Nx3 indices into self._vertices, 3 verts/face
123
+ self._edges = None # Nx2 indices into self._vertices, 2 verts/edge
124
+ self._edges_indexed_by_faces = None # (Ne, 3, 2) indices into
125
+ # self._vertices, 3 edge / face and 2 verts/edge
126
+ # inverse mappings
127
+ self._vertex_faces = None # maps vertex ID to a list of face IDs
128
+ self._vertex_edges = None # maps vertex ID to a list of edge IDs
129
+
130
+ # Per-vertex data
131
+ self._vertex_normals = None # (Nv, 3) normals
132
+ self._vertex_normals_indexed_by_faces = None # (Nf, 3, 3) normals
133
+ self._vertex_colors = None # (Nv, 4) colors
134
+ self._vertex_colors_indexed_by_faces = None # (Nf, 3, 4) colors
135
+ self._vertex_colors_indexed_by_edges = None # (Nf, 2, 4) colors
136
+ self._vertex_values = None # (Nv,) values
137
+ self._vertex_values_indexed_by_faces = None # (Nv, 3) values
138
+ self._vertex_values_indexed_by_edges = None # (Nv, 2) values
139
+
140
+ # Per-face data
141
+ self._face_normals = None # (Nf, 3) face normals
142
+ self._face_normals_indexed_by_faces = None # (Nf, 3, 3) face normals
143
+ self._face_colors = None # (Nf, 4) face colors
144
+ self._face_colors_indexed_by_faces = None # (Nf, 3, 4) face colors
145
+ self._face_colors_indexed_by_edges = None # (Ne, 2, 4) face colors
146
+
147
+ # Per-edge data
148
+ self._edge_colors = None # (Ne, 4) edge colors
149
+ self._edge_colors_indexed_by_edges = None # (Ne, 2, 4) edge colors
150
+ if vertices is not None:
151
+ indexed = 'faces' if faces is None else None
152
+ self.set_vertices(vertices, indexed=indexed)
153
+ if faces is not None:
154
+ self.set_faces(faces)
155
+ if vertex_colors is not None:
156
+ self.set_vertex_colors(vertex_colors, indexed=indexed)
157
+ if face_colors is not None:
158
+ self.set_face_colors(face_colors, indexed=indexed)
159
+ if vertex_values is not None:
160
+ self.set_vertex_values(vertex_values, indexed=indexed)
161
+
162
+ def get_faces(self):
163
+ """Array (Nf, 3) of vertex indices, three per triangular face.
164
+
165
+ If faces have not been computed for this mesh, returns None.
166
+ """
167
+ return self._faces
168
+
169
+ def get_edges(self, indexed=None):
170
+ """Edges of the mesh
171
+
172
+ Parameters
173
+ ----------
174
+ indexed : str | None
175
+ If indexed is None, return (Nf, 3) array of vertex indices,
176
+ two per edge in the mesh.
177
+ If indexed is 'faces', then return (Nf, 3, 2) array of vertex
178
+ indices with 3 edges per face, and two vertices per edge.
179
+
180
+ Returns
181
+ -------
182
+ edges : ndarray
183
+ The edges.
184
+ """
185
+ if indexed is None:
186
+ if self._edges is None:
187
+ self._compute_edges(indexed=None)
188
+ return self._edges
189
+ elif indexed == 'faces':
190
+ if self._edges_indexed_by_faces is None:
191
+ self._compute_edges(indexed='faces')
192
+ return self._edges_indexed_by_faces
193
+ else:
194
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
195
+
196
+ def set_faces(self, faces):
197
+ """Set the faces
198
+
199
+ Parameters
200
+ ----------
201
+ faces : ndarray
202
+ (Nf, 3) array of faces. Each row in the array contains
203
+ three indices into the vertex array, specifying the three corners
204
+ of a triangular face.
205
+ """
206
+ self._faces = faces
207
+ self._edges = None
208
+ self._edges_indexed_by_faces = None
209
+ self._vertex_faces = None
210
+ self._vertices_indexed_by_faces = None
211
+ self.reset_normals()
212
+ self._vertex_colors_indexed_by_faces = None
213
+ self._face_colors_indexed_by_faces = None
214
+
215
+ def get_vertices(self, indexed=None):
216
+ """Get the vertices
217
+
218
+ Parameters
219
+ ----------
220
+ indexed : str | None
221
+ If Note, return an array (N,3) of the positions of vertices in
222
+ the mesh. By default, each unique vertex appears only once.
223
+ If indexed is 'faces', then the array will instead contain three
224
+ vertices per face in the mesh (and a single vertex may appear more
225
+ than once in the array).
226
+
227
+ Returns
228
+ -------
229
+ vertices : ndarray
230
+ The vertices.
231
+ """
232
+ if indexed is None:
233
+ if (self._vertices is None and
234
+ self._vertices_indexed_by_faces is not None):
235
+ self._compute_unindexed_vertices()
236
+ return self._vertices
237
+ elif indexed == 'faces':
238
+ if (self._vertices_indexed_by_faces is None and
239
+ self._vertices is not None):
240
+ self._vertices_indexed_by_faces = \
241
+ self._vertices[self.get_faces()]
242
+ return self._vertices_indexed_by_faces
243
+ else:
244
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
245
+
246
+ def get_bounds(self):
247
+ """Get the mesh bounds
248
+
249
+ Returns
250
+ -------
251
+ bounds : list
252
+ A list of tuples of mesh bounds.
253
+ """
254
+ if self._vertices_indexed_by_faces is not None:
255
+ v = self._vertices_indexed_by_faces
256
+ elif self._vertices is not None:
257
+ v = self._vertices
258
+ else:
259
+ return None
260
+ bounds = [(v[:, ax].min(), v[:, ax].max()) for ax in range(v.shape[1])]
261
+ return bounds
262
+
263
+ def set_vertices(self, verts=None, indexed=None, reset_normals=True):
264
+ """Set the mesh vertices
265
+
266
+ Parameters
267
+ ----------
268
+ verts : ndarray | None
269
+ The array (Nv, 3) of vertex coordinates.
270
+ indexed : str | None
271
+ If indexed=='faces', then the data must have shape (Nf, 3, 3) and
272
+ is assumed to be already indexed as a list of faces. This will
273
+ cause any pre-existing normal vectors to be cleared unless
274
+ reset_normals=False.
275
+ reset_normals : bool
276
+ If True, reset the normals.
277
+ """
278
+ if indexed is None:
279
+ if verts is not None:
280
+ self._vertices = verts
281
+ self._vertices_indexed_by_faces = None
282
+ elif indexed == 'faces':
283
+ self._vertices = None
284
+ if verts is not None:
285
+ self._vertices_indexed_by_faces = verts
286
+ else:
287
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
288
+
289
+ if reset_normals:
290
+ self.reset_normals()
291
+
292
+ def reset_normals(self):
293
+ self._vertex_normals = None
294
+ self._vertex_normals_indexed_by_faces = None
295
+ self._face_normals = None
296
+ self._face_normals_indexed_by_faces = None
297
+
298
+ def has_face_indexed_data(self):
299
+ """Return True if this object already has vertex positions indexed
300
+ by face
301
+ """
302
+ return self._vertices_indexed_by_faces is not None
303
+
304
+ def has_edge_indexed_data(self):
305
+ return self._vertices_indexed_by_edges is not None
306
+
307
+ def has_vertex_color(self):
308
+ """Return True if this data set has vertex color information"""
309
+ for v in (self._vertex_colors, self._vertex_colors_indexed_by_faces,
310
+ self._vertex_colors_indexed_by_edges):
311
+ if v is not None:
312
+ return True
313
+ return False
314
+
315
+ def has_vertex_value(self):
316
+ """Return True if this data set has vertex value information"""
317
+ for v in (self._vertex_values, self._vertex_values_indexed_by_faces,
318
+ self._vertex_values_indexed_by_edges):
319
+ if v is not None:
320
+ return True
321
+ return False
322
+
323
+ def has_face_color(self):
324
+ """Return True if this data set has face color information"""
325
+ for v in (self._face_colors, self._face_colors_indexed_by_faces,
326
+ self._face_colors_indexed_by_edges):
327
+ if v is not None:
328
+ return True
329
+ return False
330
+
331
+ def get_face_normals(self, indexed=None):
332
+ """Get face normals
333
+
334
+ Parameters
335
+ ----------
336
+ indexed : str | None
337
+ If None, return an array (Nf, 3) of normal vectors for each face.
338
+ If 'faces', then instead return an indexed array (Nf, 3, 3)
339
+ (this is just the same array with each vector copied three times).
340
+
341
+ Returns
342
+ -------
343
+ normals : ndarray
344
+ The normals.
345
+ """
346
+ if indexed not in (None, 'faces'):
347
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
348
+
349
+ if self._face_normals is None:
350
+ vertices = self.get_vertices(indexed='faces')
351
+ self._face_normals = _compute_face_normals(vertices)
352
+
353
+ if indexed == 'faces' and self._face_normals_indexed_by_faces is None:
354
+ self._face_normals_indexed_by_faces = \
355
+ _repeat_face_normals_on_corners(self._face_normals)
356
+
357
+ return (self._face_normals if indexed is None
358
+ else self._face_normals_indexed_by_faces)
359
+
360
+ def get_vertex_normals(self, indexed=None):
361
+ """Get vertex normals
362
+
363
+ Parameters
364
+ ----------
365
+ indexed : str | None
366
+ If None, return an (N, 3) array of normal vectors with one entry
367
+ per unique vertex in the mesh. If indexed is 'faces', then the
368
+ array will contain three normal vectors per face (and some
369
+ vertices may be repeated).
370
+
371
+ Returns
372
+ -------
373
+ normals : ndarray
374
+ The normals.
375
+ """
376
+ if indexed not in (None, 'faces'):
377
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
378
+
379
+ if self._vertex_normals is None:
380
+ face_normals = self.get_face_normals()
381
+ faces = self.get_faces()
382
+ vertices = self.get_vertices()
383
+ self._vertex_normals = _compute_vertex_normals(face_normals, faces,
384
+ vertices)
385
+
386
+ if indexed is None:
387
+ return self._vertex_normals
388
+ elif indexed == 'faces':
389
+ return self._vertex_normals[self.get_faces()]
390
+
391
+ def get_vertex_colors(self, indexed=None):
392
+ """Get vertex colors
393
+
394
+ Parameters
395
+ ----------
396
+ indexed : str | None
397
+ If None, return an array (Nv, 4) of vertex colors.
398
+ If indexed=='faces', then instead return an indexed array
399
+ (Nf, 3, 4).
400
+
401
+ Returns
402
+ -------
403
+ colors : ndarray
404
+ The vertex colors.
405
+ """
406
+ if indexed is None:
407
+ return self._vertex_colors
408
+ elif indexed == 'faces':
409
+ if self._vertex_colors_indexed_by_faces is None:
410
+ self._vertex_colors_indexed_by_faces = \
411
+ self._vertex_colors[self.get_faces()]
412
+ return self._vertex_colors_indexed_by_faces
413
+ else:
414
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
415
+
416
+ def get_vertex_values(self, indexed=None):
417
+ """Get vertex colors
418
+
419
+ Parameters
420
+ ----------
421
+ indexed : str | None
422
+ If None, return an array (Nv,) of vertex values.
423
+ If indexed=='faces', then instead return an indexed array
424
+ (Nf, 3).
425
+
426
+ Returns
427
+ -------
428
+ values : ndarray
429
+ The vertex values.
430
+ """
431
+ if indexed is None:
432
+ return self._vertex_values
433
+ elif indexed == 'faces':
434
+ if self._vertex_values_indexed_by_faces is None:
435
+ self._vertex_values_indexed_by_faces = \
436
+ self._vertex_values[self.get_faces()]
437
+ return self._vertex_values_indexed_by_faces
438
+ else:
439
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
440
+
441
+ def set_vertex_colors(self, colors, indexed=None):
442
+ """Set the vertex color array
443
+
444
+ Parameters
445
+ ----------
446
+ colors : array
447
+ Array of colors. Must have shape (Nv, 4) (indexing by vertex)
448
+ or shape (Nf, 3, 4) (vertices indexed by face).
449
+ indexed : str | None
450
+ Should be 'faces' if colors are indexed by faces.
451
+ """
452
+ colors = _fix_colors(colors)
453
+ if indexed is None:
454
+ if colors.ndim != 2:
455
+ raise ValueError('colors must be 2D if indexed is None')
456
+ if colors.shape[0] != self.n_vertices:
457
+ raise ValueError('incorrect number of colors %s, expected %s'
458
+ % (colors.shape[0], self.n_vertices))
459
+ self._vertex_colors = colors
460
+ self._vertex_colors_indexed_by_faces = None
461
+ elif indexed == 'faces':
462
+ if colors.ndim != 3:
463
+ raise ValueError('colors must be 3D if indexed is "faces"')
464
+ if colors.shape[0] != self.n_faces:
465
+ raise ValueError('incorrect number of faces')
466
+ self._vertex_colors = None
467
+ self._vertex_colors_indexed_by_faces = colors
468
+ else:
469
+ raise ValueError('indexed must be None or "faces"')
470
+
471
+ def set_vertex_values(self, values, indexed=None):
472
+ """Set the vertex value array
473
+
474
+ Parameters
475
+ ----------
476
+ values : array
477
+ Array of values. Must have shape (Nv,) (indexing by vertex)
478
+ or shape (Nf, 3) (vertices indexed by face).
479
+ indexed : str | None
480
+ Should be 'faces' if colors are indexed by faces.
481
+ """
482
+ values = np.asarray(values)
483
+ if indexed is None:
484
+ if values.ndim != 1:
485
+ raise ValueError('values must be 1D if indexed is None')
486
+ if values.shape[0] != self.n_vertices:
487
+ raise ValueError('incorrect number of colors %s, expected %s'
488
+ % (values.shape[0], self.n_vertices))
489
+ self._vertex_values = values
490
+ self._vertex_values_indexed_by_faces = None
491
+ elif indexed == 'faces':
492
+ if values.ndim != 2:
493
+ raise ValueError('values must be 3D if indexed is "faces"')
494
+ if values.shape[0] != self.n_faces:
495
+ raise ValueError('incorrect number of faces')
496
+ self._vertex_values = None
497
+ self._vertex_values_indexed_by_faces = values
498
+ else:
499
+ raise ValueError('indexed must be None or "faces"')
500
+
501
+ def get_face_colors(self, indexed=None):
502
+ """Get the face colors
503
+
504
+ Parameters
505
+ ----------
506
+ indexed : str | None
507
+ If indexed is None, return (Nf, 4) array of face colors.
508
+ If indexed=='faces', then instead return an indexed array
509
+ (Nf, 3, 4) (note this is just the same array with each color
510
+ repeated three times).
511
+
512
+ Returns
513
+ -------
514
+ colors : ndarray
515
+ The colors.
516
+ """
517
+ if indexed is None:
518
+ return self._face_colors
519
+ elif indexed == 'faces':
520
+ if (self._face_colors_indexed_by_faces is None and
521
+ self._face_colors is not None):
522
+ Nf = self._face_colors.shape[0]
523
+ self._face_colors_indexed_by_faces = \
524
+ np.empty((Nf, 3, 4), dtype=self._face_colors.dtype)
525
+ self._face_colors_indexed_by_faces[:] = \
526
+ self._face_colors.reshape(Nf, 1, 4)
527
+ return self._face_colors_indexed_by_faces
528
+ else:
529
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
530
+
531
+ def set_face_colors(self, colors, indexed=None):
532
+ """Set the face color array
533
+
534
+ Parameters
535
+ ----------
536
+ colors : array
537
+ Array of colors. Must have shape (Nf, 4) (indexed by face),
538
+ or shape (Nf, 3, 4) (face colors indexed by faces).
539
+ indexed : str | None
540
+ Should be 'faces' if colors are indexed by faces.
541
+ """
542
+ colors = _fix_colors(colors)
543
+ if colors.shape[0] != self.n_faces:
544
+ raise ValueError('incorrect number of colors %s, expected %s'
545
+ % (colors.shape[0], self.n_faces))
546
+ if indexed is None:
547
+ if colors.ndim != 2:
548
+ raise ValueError('colors must be 2D if indexed is None')
549
+ self._face_colors = colors
550
+ self._face_colors_indexed_by_faces = None
551
+ elif indexed == 'faces':
552
+ if colors.ndim != 3:
553
+ raise ValueError('colors must be 3D if indexed is "faces"')
554
+ self._face_colors = None
555
+ self._face_colors_indexed_by_faces = colors
556
+ else:
557
+ raise ValueError('indexed must be None or "faces"')
558
+
559
+ @property
560
+ def n_faces(self):
561
+ """The number of faces in the mesh"""
562
+ if self._faces is not None:
563
+ return self._faces.shape[0]
564
+ elif self._vertices_indexed_by_faces is not None:
565
+ return self._vertices_indexed_by_faces.shape[0]
566
+
567
+ @property
568
+ def n_vertices(self):
569
+ """The number of vertices in the mesh"""
570
+ if self._vertices is None:
571
+ self._compute_unindexed_vertices()
572
+ return len(self._vertices)
573
+
574
+ def get_edge_colors(self):
575
+ return self._edge_colors
576
+
577
+ def _compute_unindexed_vertices(self):
578
+ # Given (Nv, 3, 3) array of vertices-indexed-by-face, convert
579
+ # backward to unindexed vertices
580
+ # This is done by collapsing into a list of 'unique' vertices
581
+ # (difference < 1e-14)
582
+
583
+ # I think generally this should be discouraged..
584
+ faces = self._vertices_indexed_by_faces
585
+ verts = {} # used to remember the index of each vertex position
586
+ self._faces = np.empty(faces.shape[:2], dtype=np.uint32)
587
+ self._vertices = []
588
+ self._vertex_faces = []
589
+ self._face_normals = None
590
+ self._vertex_normals = None
591
+ for i in range(faces.shape[0]):
592
+ face = faces[i]
593
+ for j in range(face.shape[0]):
594
+ pt = face[j]
595
+ # quantize to ensure nearly-identical points will be merged
596
+ pt2 = tuple([round(x*1e14) for x in pt])
597
+ index = verts.get(pt2, None)
598
+ if index is None:
599
+ self._vertices.append(pt)
600
+ self._vertex_faces.append([])
601
+ index = len(self._vertices)-1
602
+ verts[pt2] = index
603
+ # track which vertices belong to which faces
604
+ self._vertex_faces[index].append(i)
605
+ self._faces[i, j] = index
606
+ self._vertices = np.array(self._vertices, dtype=np.float32)
607
+
608
+ def get_vertex_faces(self):
609
+ """List mapping each vertex index to a list of face indices that use it."""
610
+ if self._vertex_faces is None:
611
+ self._vertex_faces = [[] for i in range(len(self.get_vertices()))]
612
+ for i in range(self._faces.shape[0]):
613
+ face = self._faces[i]
614
+ for ind in face:
615
+ self._vertex_faces[ind].append(i)
616
+ return self._vertex_faces
617
+
618
+ def _compute_edges(self, indexed=None):
619
+ if indexed is None:
620
+ if self._faces is not None:
621
+ # generate self._edges from self._faces
622
+ nf = len(self._faces)
623
+ edges = np.empty(nf*3, dtype=[('i', np.uint32, 2)])
624
+ edges['i'][0:nf] = self._faces[:, :2]
625
+ edges['i'][nf:2*nf] = self._faces[:, 1:3]
626
+ edges['i'][-nf:, 0] = self._faces[:, 2]
627
+ edges['i'][-nf:, 1] = self._faces[:, 0]
628
+ # sort per-edge
629
+ mask = edges['i'][:, 0] > edges['i'][:, 1]
630
+ edges['i'][mask] = edges['i'][mask][:, ::-1]
631
+ # remove duplicate entries
632
+ self._edges = np.unique(edges)['i']
633
+ else:
634
+ raise Exception("MeshData cannot generate edges--no faces in "
635
+ "this data.")
636
+ elif indexed == 'faces':
637
+ if self._vertices_indexed_by_faces is not None:
638
+ verts = self._vertices_indexed_by_faces
639
+ edges = np.empty((verts.shape[0], 3, 2), dtype=np.uint32)
640
+ nf = verts.shape[0]
641
+ edges[:, 0, 0] = np.arange(nf) * 3
642
+ edges[:, 0, 1] = edges[:, 0, 0] + 1
643
+ edges[:, 1, 0] = edges[:, 0, 1]
644
+ edges[:, 1, 1] = edges[:, 1, 0] + 1
645
+ edges[:, 2, 0] = edges[:, 1, 1]
646
+ edges[:, 2, 1] = edges[:, 0, 0]
647
+ self._edges_indexed_by_faces = edges
648
+ else:
649
+ raise Exception("MeshData cannot generate edges--no faces in "
650
+ "this data.")
651
+ else:
652
+ raise ValueError("Invalid indexing mode. Accepts: None, 'faces'")
653
+
654
+ def save(self):
655
+ """Serialize this mesh to a string appropriate for disk storage
656
+
657
+ Returns
658
+ -------
659
+ state : dict
660
+ The state.
661
+ """
662
+ import pickle
663
+ if self._faces is not None:
664
+ names = ['_vertices', '_faces']
665
+ else:
666
+ names = ['_vertices_indexed_by_faces']
667
+
668
+ if self._vertex_colors is not None:
669
+ names.append('_vertex_colors')
670
+ elif self._vertex_colors_indexed_by_faces is not None:
671
+ names.append('_vertex_colors_indexed_by_faces')
672
+
673
+ if self._face_colors is not None:
674
+ names.append('_face_colors')
675
+ elif self._face_colors_indexed_by_faces is not None:
676
+ names.append('_face_colors_indexed_by_faces')
677
+
678
+ state = dict([(n, getattr(self, n)) for n in names])
679
+ return pickle.dumps(state)
680
+
681
+ def restore(self, state):
682
+ """Restore the state of a mesh previously saved using save()
683
+
684
+ Parameters
685
+ ----------
686
+ state : dict
687
+ The previous state.
688
+ """
689
+ import pickle
690
+ state = pickle.loads(state)
691
+ for k in state:
692
+ if isinstance(state[k], list):
693
+ state[k] = np.array(state[k])
694
+ setattr(self, k, state[k])
695
+
696
+ def is_empty(self):
697
+ """Check if any vertices or faces are defined."""
698
+ return self._faces is None