snappy 3.0.3__cp38-cp38-macosx_11_0_arm64.whl → 3.2__cp38-cp38-macosx_11_0_arm64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (401) hide show
  1. snappy/CyOpenGL.cpython-38-darwin.so +0 -0
  2. snappy/SnapPy.cpython-38-darwin.so +0 -0
  3. snappy/SnapPyHP.cpython-38-darwin.so +0 -0
  4. snappy/__init__.py +373 -426
  5. snappy/app.py +240 -75
  6. snappy/app_menus.py +93 -78
  7. snappy/browser.py +87 -63
  8. snappy/cache.py +5 -8
  9. snappy/canonical.py +249 -0
  10. snappy/{verify/cusp_shapes.py → cusps/__init__.py} +11 -19
  11. snappy/cusps/cusp_area_matrix.py +101 -0
  12. snappy/{verify/cusp_areas.py → cusps/cusp_areas_from_matrix.py} +39 -54
  13. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  14. snappy/cusps/test.py +21 -0
  15. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  16. snappy/database.py +40 -31
  17. snappy/db_utilities.py +13 -14
  18. snappy/decorated_isosig.py +377 -133
  19. snappy/dev/extended_ptolemy/complexVolumesClosed.py +42 -9
  20. snappy/dev/extended_ptolemy/extended.py +32 -25
  21. snappy/dev/extended_ptolemy/giac_rur.py +23 -8
  22. snappy/dev/extended_ptolemy/phc_wrapper.py +10 -10
  23. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +2 -1
  24. snappy/dev/vericlosed/gimbalLoopFinder.py +5 -5
  25. snappy/dev/vericlosed/hyperbolicStructure.py +3 -3
  26. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +2 -2
  27. snappy/dev/vericlosed/truncatedComplex.py +3 -2
  28. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +4 -3
  29. snappy/doc/_images/geodesics.jpg +0 -0
  30. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  31. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  32. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  33. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  34. snappy/doc/_sources/additional_classes.rst.txt +1 -0
  35. snappy/doc/_sources/credits.rst.txt +6 -1
  36. snappy/doc/_sources/development.rst.txt +69 -50
  37. snappy/doc/_sources/index.rst.txt +101 -66
  38. snappy/doc/_sources/installing.rst.txt +148 -165
  39. snappy/doc/_sources/news.rst.txt +136 -32
  40. snappy/doc/_sources/ptolemy.rst.txt +1 -1
  41. snappy/doc/_sources/ptolemy_examples1.rst.txt +9 -8
  42. snappy/doc/_sources/ptolemy_examples2.rst.txt +3 -3
  43. snappy/doc/_sources/ptolemy_examples3.rst.txt +14 -14
  44. snappy/doc/_sources/ptolemy_prelim.rst.txt +1 -1
  45. snappy/doc/_sources/snap.rst.txt +2 -2
  46. snappy/doc/_sources/snappy.rst.txt +1 -1
  47. snappy/doc/_sources/triangulation.rst.txt +3 -2
  48. snappy/doc/_sources/verify.rst.txt +89 -29
  49. snappy/doc/_sources/verify_internals.rst.txt +5 -16
  50. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  51. snappy/doc/_static/SnapPy.ico +0 -0
  52. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  53. snappy/doc/_static/basic.css +47 -27
  54. snappy/doc/_static/css/badge_only.css +1 -0
  55. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  56. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  57. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  58. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  59. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  60. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  61. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  62. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  63. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  64. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  65. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  66. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  67. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  68. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  69. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  70. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  71. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  72. snappy/doc/_static/css/theme.css +4 -0
  73. snappy/doc/_static/doctools.js +107 -274
  74. snappy/doc/_static/documentation_options.js +6 -5
  75. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  76. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  77. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  78. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  79. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  80. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  81. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  82. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  83. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  84. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  85. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  86. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  87. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  88. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  89. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  90. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  91. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  92. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  93. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  94. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  95. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  96. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  97. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  98. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  99. snappy/doc/_static/jquery.js +2 -2
  100. snappy/doc/_static/js/badge_only.js +1 -0
  101. snappy/doc/_static/js/theme.js +1 -0
  102. snappy/doc/_static/js/versions.js +228 -0
  103. snappy/doc/_static/language_data.js +3 -101
  104. snappy/doc/_static/pygments.css +1 -0
  105. snappy/doc/_static/searchtools.js +489 -398
  106. snappy/doc/_static/snappy_furo.css +33 -0
  107. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  108. snappy/doc/_static/sphinx_highlight.js +154 -0
  109. snappy/doc/additional_classes.html +688 -263
  110. snappy/doc/bugs.html +107 -94
  111. snappy/doc/censuses.html +155 -127
  112. snappy/doc/credits.html +115 -104
  113. snappy/doc/development.html +184 -146
  114. snappy/doc/genindex.html +287 -204
  115. snappy/doc/index.html +189 -150
  116. snappy/doc/installing.html +259 -266
  117. snappy/doc/manifold.html +1626 -592
  118. snappy/doc/manifoldhp.html +119 -105
  119. snappy/doc/news.html +198 -104
  120. snappy/doc/objects.inv +0 -0
  121. snappy/doc/other.html +117 -105
  122. snappy/doc/platonic_census.html +161 -114
  123. snappy/doc/plink.html +113 -105
  124. snappy/doc/ptolemy.html +131 -108
  125. snappy/doc/ptolemy_classes.html +242 -223
  126. snappy/doc/ptolemy_examples1.html +144 -130
  127. snappy/doc/ptolemy_examples2.html +141 -129
  128. snappy/doc/ptolemy_examples3.html +148 -132
  129. snappy/doc/ptolemy_examples4.html +131 -111
  130. snappy/doc/ptolemy_prelim.html +162 -138
  131. snappy/doc/py-modindex.html +104 -69
  132. snappy/doc/screenshots.html +117 -108
  133. snappy/doc/search.html +115 -84
  134. snappy/doc/searchindex.js +1 -1
  135. snappy/doc/snap.html +109 -96
  136. snappy/doc/snappy.html +134 -97
  137. snappy/doc/spherogram.html +259 -187
  138. snappy/doc/todo.html +107 -94
  139. snappy/doc/triangulation.html +1380 -111
  140. snappy/doc/tutorial.html +107 -94
  141. snappy/doc/verify.html +194 -125
  142. snappy/doc/verify_internals.html +248 -686
  143. snappy/drilling/__init__.py +456 -0
  144. snappy/drilling/barycentric.py +103 -0
  145. snappy/drilling/constants.py +5 -0
  146. snappy/drilling/crush.py +270 -0
  147. snappy/drilling/cusps.py +125 -0
  148. snappy/drilling/debug.py +242 -0
  149. snappy/drilling/epsilons.py +6 -0
  150. snappy/drilling/exceptions.py +55 -0
  151. snappy/drilling/moves.py +620 -0
  152. snappy/drilling/peripheral_curves.py +210 -0
  153. snappy/drilling/perturb.py +188 -0
  154. snappy/drilling/shorten.py +36 -0
  155. snappy/drilling/subdivide.py +274 -0
  156. snappy/drilling/test.py +23 -0
  157. snappy/drilling/test_cases.py +126 -0
  158. snappy/drilling/tracing.py +351 -0
  159. snappy/exceptions.py +23 -3
  160. snappy/export_stl.py +20 -14
  161. snappy/exterior_to_link/__init__.py +2 -0
  162. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  163. snappy/exterior_to_link/exceptions.py +6 -0
  164. snappy/exterior_to_link/geodesic_map.json +14408 -0
  165. snappy/exterior_to_link/hyp_utils.py +112 -0
  166. snappy/exterior_to_link/link_projection.py +323 -0
  167. snappy/exterior_to_link/main.py +197 -0
  168. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  169. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  170. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  171. snappy/exterior_to_link/pl_utils.py +491 -0
  172. snappy/exterior_to_link/put_in_S3.py +156 -0
  173. snappy/exterior_to_link/rational_linear_algebra.py +123 -0
  174. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  175. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  176. snappy/exterior_to_link/stored_moves.py +475 -0
  177. snappy/exterior_to_link/test.py +31 -0
  178. snappy/geometric_structure/__init__.py +212 -0
  179. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  180. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +697 -0
  181. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
  182. snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
  183. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
  184. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
  185. snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -0
  186. snappy/geometric_structure/geodesic/__init__.py +0 -0
  187. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  188. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  189. snappy/geometric_structure/geodesic/canonical_keys.py +52 -0
  190. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  191. snappy/geometric_structure/geodesic/constants.py +6 -0
  192. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  193. snappy/geometric_structure/geodesic/fixed_points.py +93 -0
  194. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  195. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  196. snappy/geometric_structure/geodesic/line.py +30 -0
  197. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  198. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +101 -0
  199. snappy/geometric_structure/test.py +22 -0
  200. snappy/gui.py +36 -36
  201. snappy/horoviewer.py +50 -48
  202. snappy/hyperboloid/__init__.py +212 -0
  203. snappy/hyperboloid/distances.py +245 -0
  204. snappy/hyperboloid/horoball.py +19 -0
  205. snappy/hyperboloid/line.py +35 -0
  206. snappy/hyperboloid/point.py +9 -0
  207. snappy/hyperboloid/triangle.py +29 -0
  208. snappy/{infodialog.py → infowindow.py} +32 -33
  209. snappy/isometry_signature.py +382 -0
  210. snappy/len_spec/__init__.py +596 -0
  211. snappy/len_spec/geodesic_info.py +110 -0
  212. snappy/len_spec/geodesic_key_info_dict.py +117 -0
  213. snappy/len_spec/geodesic_piece.py +143 -0
  214. snappy/len_spec/geometric_structure.py +182 -0
  215. snappy/len_spec/geometry.py +80 -0
  216. snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
  217. snappy/len_spec/spine.py +206 -0
  218. snappy/len_spec/test.py +24 -0
  219. snappy/len_spec/test_cases.py +69 -0
  220. snappy/len_spec/tile.py +275 -0
  221. snappy/len_spec/word.py +86 -0
  222. snappy/manifolds/__init__.py +1 -1
  223. snappy/math_basics.py +176 -0
  224. snappy/matrix.py +525 -0
  225. snappy/number.py +97 -21
  226. snappy/numeric_output_checker.py +37 -27
  227. snappy/pari.py +30 -69
  228. snappy/phone_home.py +25 -20
  229. snappy/polyviewer.py +39 -37
  230. snappy/ptolemy/__init__.py +4 -6
  231. snappy/ptolemy/component.py +14 -12
  232. snappy/ptolemy/coordinates.py +312 -295
  233. snappy/ptolemy/fieldExtensions.py +14 -12
  234. snappy/ptolemy/findLoops.py +43 -31
  235. snappy/ptolemy/geometricRep.py +24 -26
  236. snappy/ptolemy/homology.py +12 -7
  237. snappy/ptolemy/manifoldMethods.py +69 -70
  238. snappy/ptolemy/matrix.py +65 -26
  239. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +18 -14
  240. snappy/ptolemy/polynomial.py +125 -119
  241. snappy/ptolemy/processComponents.py +36 -30
  242. snappy/ptolemy/processFileBase.py +79 -18
  243. snappy/ptolemy/processFileDispatch.py +13 -14
  244. snappy/ptolemy/processMagmaFile.py +44 -39
  245. snappy/ptolemy/processRurFile.py +18 -11
  246. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +20 -17
  247. snappy/ptolemy/ptolemyObstructionClass.py +13 -17
  248. snappy/ptolemy/ptolemyVariety.py +190 -121
  249. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +20 -19
  250. snappy/ptolemy/reginaWrapper.py +25 -29
  251. snappy/ptolemy/rur.py +6 -14
  252. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +27 -22
  253. snappy/ptolemy/test.py +247 -188
  254. snappy/ptolemy/utilities.py +41 -43
  255. snappy/raytracing/__init__.py +64 -0
  256. snappy/raytracing/additional_horospheres.py +64 -0
  257. snappy/raytracing/additional_len_spec_choices.py +63 -0
  258. snappy/raytracing/cohomology_fractal.py +10 -6
  259. snappy/raytracing/eyeball.py +123 -0
  260. snappy/raytracing/finite_raytracing_data.py +48 -38
  261. snappy/raytracing/finite_viewer.py +218 -210
  262. snappy/raytracing/geodesic_tube_info.py +174 -0
  263. snappy/raytracing/geodesics.py +246 -0
  264. snappy/raytracing/geodesics_window.py +258 -0
  265. snappy/raytracing/gui_utilities.py +152 -40
  266. snappy/raytracing/hyperboloid_navigation.py +102 -52
  267. snappy/raytracing/hyperboloid_utilities.py +114 -261
  268. snappy/raytracing/ideal_raytracing_data.py +256 -179
  269. snappy/raytracing/inside_viewer.py +522 -253
  270. snappy/raytracing/pack.py +22 -0
  271. snappy/raytracing/raytracing_data.py +46 -34
  272. snappy/raytracing/raytracing_view.py +190 -109
  273. snappy/raytracing/shaders/Eye.png +0 -0
  274. snappy/raytracing/shaders/NonGeometric.png +0 -0
  275. snappy/raytracing/shaders/__init__.py +60 -4
  276. snappy/raytracing/shaders/fragment.glsl +575 -148
  277. snappy/raytracing/test.py +29 -0
  278. snappy/raytracing/tooltip.py +146 -0
  279. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  280. snappy/raytracing/view_scale_controller.py +98 -0
  281. snappy/raytracing/zoom_slider/__init__.py +32 -29
  282. snappy/raytracing/zoom_slider/test.py +2 -0
  283. snappy/sage_helper.py +69 -123
  284. snappy/{preferences.py → settings.py} +167 -145
  285. snappy/shell.py +4 -0
  286. snappy/snap/__init__.py +12 -8
  287. snappy/snap/character_varieties.py +24 -18
  288. snappy/snap/find_field.py +35 -34
  289. snappy/snap/fundamental_polyhedron.py +99 -85
  290. snappy/snap/generators.py +6 -8
  291. snappy/snap/interval_reps.py +18 -6
  292. snappy/snap/kernel_structures.py +8 -3
  293. snappy/snap/mcomplex_base.py +1 -2
  294. snappy/snap/nsagetools.py +107 -53
  295. snappy/snap/peripheral/__init__.py +1 -1
  296. snappy/snap/peripheral/dual_cellulation.py +15 -7
  297. snappy/snap/peripheral/link.py +20 -16
  298. snappy/snap/peripheral/peripheral.py +22 -14
  299. snappy/snap/peripheral/surface.py +47 -50
  300. snappy/snap/peripheral/test.py +8 -8
  301. snappy/snap/polished_reps.py +65 -40
  302. snappy/snap/shapes.py +41 -22
  303. snappy/snap/slice_obs_HKL.py +64 -25
  304. snappy/snap/t3mlite/arrow.py +88 -51
  305. snappy/snap/t3mlite/corner.py +5 -6
  306. snappy/snap/t3mlite/edge.py +32 -21
  307. snappy/snap/t3mlite/face.py +7 -9
  308. snappy/snap/t3mlite/files.py +31 -23
  309. snappy/snap/t3mlite/homology.py +14 -10
  310. snappy/snap/t3mlite/linalg.py +158 -56
  311. snappy/snap/t3mlite/mcomplex.py +739 -291
  312. snappy/snap/t3mlite/perm4.py +236 -84
  313. snappy/snap/t3mlite/setup.py +9 -10
  314. snappy/snap/t3mlite/simplex.py +65 -48
  315. snappy/snap/t3mlite/spun.py +42 -30
  316. snappy/snap/t3mlite/surface.py +45 -45
  317. snappy/snap/t3mlite/test.py +3 -0
  318. snappy/snap/t3mlite/test_vs_regina.py +17 -13
  319. snappy/snap/t3mlite/tetrahedron.py +25 -24
  320. snappy/snap/t3mlite/vertex.py +8 -13
  321. snappy/snap/test.py +45 -52
  322. snappy/snap/utilities.py +66 -65
  323. snappy/test.py +155 -158
  324. snappy/test_cases.py +263 -0
  325. snappy/testing.py +131 -0
  326. snappy/tiling/__init__.py +2 -0
  327. snappy/tiling/canonical_key_dict.py +59 -0
  328. snappy/tiling/dict_based_set.py +79 -0
  329. snappy/tiling/floor.py +49 -0
  330. snappy/tiling/hyperboloid_dict.py +54 -0
  331. snappy/tiling/iter_utils.py +78 -0
  332. snappy/tiling/lifted_tetrahedron.py +22 -0
  333. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  334. snappy/tiling/real_hash_dict.py +164 -0
  335. snappy/tiling/test.py +23 -0
  336. snappy/tiling/tile.py +215 -0
  337. snappy/tiling/triangle.py +33 -0
  338. snappy/tkterminal.py +313 -203
  339. snappy/twister/main.py +1 -8
  340. snappy/twister/twister_core.cpython-38-darwin.so +0 -0
  341. snappy/upper_halfspace/__init__.py +146 -0
  342. snappy/upper_halfspace/ideal_point.py +26 -0
  343. snappy/verify/__init__.py +4 -8
  344. snappy/verify/{verifyCanonical.py → canonical.py} +114 -97
  345. snappy/verify/complex_volume/__init__.py +3 -2
  346. snappy/verify/complex_volume/adjust_torsion.py +13 -11
  347. snappy/verify/complex_volume/closed.py +29 -24
  348. snappy/verify/complex_volume/compute_ptolemys.py +8 -6
  349. snappy/verify/complex_volume/cusped.py +10 -9
  350. snappy/verify/complex_volume/extended_bloch.py +14 -12
  351. snappy/verify/{cuspTranslations.py → cusp_translations.py} +15 -14
  352. snappy/verify/edge_equations.py +80 -0
  353. snappy/verify/exceptions.py +23 -56
  354. snappy/verify/{verifyHyperbolicity.py → hyperbolicity.py} +19 -15
  355. snappy/verify/interval_newton_shapes_engine.py +51 -211
  356. snappy/verify/interval_tree.py +27 -25
  357. snappy/verify/krawczyk_shapes_engine.py +47 -50
  358. snappy/verify/maximal_cusp_area_matrix/__init__.py +17 -86
  359. snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +58 -48
  360. snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +53 -57
  361. snappy/verify/{realAlgebra.py → real_algebra.py} +26 -20
  362. snappy/verify/shapes.py +10 -7
  363. snappy/verify/short_slopes.py +41 -42
  364. snappy/verify/{squareExtensions.py → square_extensions.py} +96 -92
  365. snappy/verify/test.py +59 -57
  366. snappy/verify/upper_halfspace/extended_matrix.py +5 -5
  367. snappy/verify/upper_halfspace/finite_point.py +44 -31
  368. snappy/verify/upper_halfspace/ideal_point.py +69 -57
  369. snappy/verify/volume.py +15 -12
  370. snappy/version.py +2 -3
  371. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/METADATA +14 -12
  372. snappy-3.2.dist-info/RECORD +503 -0
  373. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/WHEEL +1 -1
  374. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/entry_points.txt +0 -1
  375. {snappy-3.0.3.dist-info → snappy-3.2.dist-info}/top_level.txt +10 -1
  376. snappy/doc/_sources/verify_canon.rst.txt +0 -90
  377. snappy/doc/_static/classic.css +0 -266
  378. snappy/doc/_static/jquery-3.5.1.js +0 -10872
  379. snappy/doc/_static/sidebar.js +0 -159
  380. snappy/doc/_static/underscore-1.13.1.js +0 -2042
  381. snappy/doc/_static/underscore.js +0 -6
  382. snappy/doc/verify_canon.html +0 -283
  383. snappy/ppm_to_png.py +0 -243
  384. snappy/togl/__init__.py +0 -3
  385. snappy/togl/darwin-tk8.6/Togl2.1/LICENSE +0 -28
  386. snappy/togl/darwin-tk8.6/Togl2.1/libTogl2.1.dylib +0 -0
  387. snappy/togl/darwin-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
  388. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
  389. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/libTogl2.1.so +0 -0
  390. snappy/togl/linux2-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -5
  391. snappy/togl/win32VC-tk8.6/Togl2.1/LICENSE +0 -28
  392. snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.dll +0 -0
  393. snappy/togl/win32VC-tk8.6/Togl2.1/Togl21.lib +0 -0
  394. snappy/togl/win32VC-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
  395. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/LICENSE +0 -28
  396. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.dll +0 -0
  397. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/Togl21.lib +0 -0
  398. snappy/togl/win32VC-x86_64-tk8.6/Togl2.1/pkgIndex.tcl +0 -6
  399. snappy/verify/cuspCrossSection.py +0 -1413
  400. snappy/verify/mathHelpers.py +0 -64
  401. snappy-3.0.3.dist-info/RECORD +0 -360
@@ -1,70 +1,77 @@
1
- import sys, tkinter
1
+ import sys
2
+ import tkinter
2
3
  from tkinter import ttk
3
4
  from .zoom_slider import Slider
4
5
  import time
5
6
 
6
7
  if sys.platform == 'linux':
7
- label_pad, slider_stick = (4, 0), tkinter.EW
8
+ label_pad, slider_stick = (4, 0, 20, 0), tkinter.EW
8
9
  else:
9
10
  label_pad, slider_stick = 0, tkinter.NSEW
10
11
 
12
+
11
13
  class UniformDictController:
12
14
  @staticmethod
13
15
  def create_horizontal_scale(container, uniform_dict, key,
14
- row, left_end, right_end, update_function = None,
15
- column = 0,
16
- title = None,
17
- format_string = None,
18
- index = None, component_index = None):
16
+ row, left_end, right_end, update_function=None,
17
+ column=0,
18
+ columnspan=1,
19
+ title=None,
20
+ format_string=None,
21
+ index=None, component_index=None):
19
22
  if title:
20
- title_label = ttk.Label(container, text = title, padding=label_pad)
21
- title_label.grid(row = row, column = column, sticky=tkinter.NE)
23
+ title_label = ttk.Label(container, text=title, padding=label_pad)
24
+ title_label.grid(row=row, column=column, sticky=tkinter.NE)
22
25
  column += 1
23
26
 
24
- scale = Slider(master = container,
25
- left_end = left_end,
26
- right_end = right_end)
27
- scale.grid(row = row, column = column, sticky = slider_stick)
28
- column += 1
27
+ scale = Slider(container=container,
28
+ left_end=left_end,
29
+ right_end=right_end)
30
+ scale.grid(row=row, column=column, columnspan=columnspan,
31
+ sticky=slider_stick, padx=10)
32
+ column += columnspan
29
33
  value_label = ttk.Label(container, padding=label_pad)
30
- value_label.grid(row = row, column = column, sticky = tkinter.NW)
34
+ value_label.grid(row=row, column=column, sticky=tkinter.NW, padx=20)
31
35
 
32
36
  if title:
33
37
  title_label.grid_configure(sticky=tkinter.N, pady=4)
34
38
 
35
39
  return UniformDictController(
36
- uniform_dict, key, scale = scale, label = value_label,
37
- update_function = update_function,
38
- format_string = format_string,
39
- index = index, component_index = component_index)
40
+ uniform_dict, key, scale=scale, label=value_label,
41
+ update_function=update_function,
42
+ format_string=format_string,
43
+ index=index, component_index=component_index)
40
44
 
41
45
  @staticmethod
42
46
  def create_checkbox(container, uniform_dict, key,
43
- row, update_function = None,
44
- column = 0,
45
- text = '',
46
- index = None,
47
- component_index = None):
47
+ row, update_function=None,
48
+ column=0,
49
+ text='',
50
+ index=None,
51
+ component_index=None,
52
+ gridargs = {}):
48
53
  checkbox = ttk.Checkbutton(container, takefocus=0)
49
- checkbox.grid(row = row, column = column)
50
- checkbox.configure(text = text)
54
+ checkbox.grid(row=row, column=column, **gridargs)
55
+ checkbox.configure(text=text)
51
56
 
52
57
  return UniformDictController(
53
- uniform_dict, key, checkbox = checkbox,
54
- update_function = update_function,
55
- index = index, component_index = component_index)
58
+ uniform_dict, key, checkbox=checkbox,
59
+ update_function=update_function,
60
+ index=index, component_index=component_index)
56
61
 
57
62
  def __init__(self, uniform_dict, key,
58
- scale = None, label = None, checkbox = None,
59
- update_function = None,
60
- format_string = None,
61
- index = None, component_index = None):
63
+ scale=None, label=None, checkbox=None,
64
+ radio_buttons=None,
65
+ update_function=None,
66
+ format_string=None,
67
+ index=None, component_index=None):
62
68
 
63
69
  self.uniform_dict = uniform_dict
64
70
  self.key = key
65
71
  self.scale = scale
66
72
  self.label = label
67
73
  self.checkbox = checkbox
74
+ self.radio_buttons = radio_buttons
68
75
  self.update_function = update_function
69
76
  self.index = index
70
77
  self.component_index = component_index
@@ -77,7 +84,7 @@ class UniformDictController:
77
84
  raise Exception("int/float uniform does not support index")
78
85
  elif self.uniform_type == 'float[]':
79
86
  self.scalar_type = 'float'
80
- if index is None or not component_index is None:
87
+ if index is None or component_index is not None:
81
88
  raise Exception("Need to specify index for float[] uniform")
82
89
  elif self.uniform_type == 'vec2[]':
83
90
  self.scalar_type = 'float'
@@ -87,6 +94,10 @@ class UniformDictController:
87
94
  self.scalar_type = 'bool'
88
95
  if not (index is None and component_index is None):
89
96
  raise Exception("int/float uniform does not support index")
97
+ elif self.uniform_type == 'bool[]':
98
+ self.scalar_type = 'bool'
99
+ if index is None or component_index is not None:
100
+ raise Exception("Need to specify index for bool[] uniform")
90
101
  else:
91
102
  raise Exception("Unsupported uniform type %s" % self.uniform_type)
92
103
 
@@ -102,8 +113,14 @@ class UniformDictController:
102
113
  self.scale.set_callback(self.scale_command)
103
114
  if self.checkbox:
104
115
  self.checkbox_var = tkinter.BooleanVar()
105
- self.checkbox.configure(variable = self.checkbox_var)
106
- self.checkbox.configure(command = self.check_command)
116
+ self.checkbox.configure(variable=self.checkbox_var)
117
+ self.checkbox.configure(command=self.check_command)
118
+ if self.radio_buttons:
119
+ self.radio_var = tkinter.IntVar()
120
+ for radio_button in self.radio_buttons:
121
+ radio_button.configure(variable=self.radio_var)
122
+ radio_button.configure(command=self.radio_command)
123
+
107
124
  self.update()
108
125
 
109
126
  def get_value(self):
@@ -118,6 +135,8 @@ class UniformDictController:
118
135
  self.uniform_dict[self.key][1][self.index][self.component_index])
119
136
  if self.uniform_type == 'bool':
120
137
  return bool(self.uniform_dict[self.key][1])
138
+ if self.uniform_type == 'bool[]':
139
+ return bool(self.uniform_dict[self.key][1][self.index])
121
140
 
122
141
  def set_value(self, value):
123
142
  if self.uniform_type == 'int':
@@ -131,23 +150,30 @@ class UniformDictController:
131
150
  float(value))
132
151
  elif self.uniform_type == 'bool':
133
152
  self.uniform_dict[self.key][1] = bool(value)
153
+ elif self.uniform_type == 'bool[]':
154
+ self.uniform_dict[self.key][1][self.index] = bool(value)
134
155
 
135
156
  def update_scale(self):
136
157
  if self.scale:
137
- self.scale.set_value(value = self.get_value())
158
+ self.scale.set_value(value=self.get_value())
138
159
 
139
160
  def update_label(self):
140
161
  if self.label:
141
- self.label.configure(text = self.format_string % self.get_value())
162
+ self.label.configure(text=self.format_string % self.get_value())
142
163
 
143
164
  def update_checkbox(self):
144
165
  if self.checkbox:
145
166
  self.checkbox_var.set(self.get_value())
146
167
 
168
+ def update_radiobuttons(self):
169
+ if self.radio_buttons:
170
+ self.radio_var.set(self.get_value())
171
+
147
172
  def update(self):
148
173
  self.update_scale()
149
174
  self.update_label()
150
175
  self.update_checkbox()
176
+ self.update_radiobuttons()
151
177
 
152
178
  def scale_command(self, value):
153
179
  self.set_value(value)
@@ -160,12 +186,29 @@ class UniformDictController:
160
186
  if self.update_function:
161
187
  self.update_function()
162
188
 
189
+ def radio_command(self):
190
+ self.set_value(self.radio_var.get())
191
+ if self.update_function:
192
+ self.update_function()
193
+
194
+
163
195
  class FpsLabelUpdater:
164
196
  def __init__(self, label):
165
197
  self.label = label
166
198
  self.num_iterations = 0
167
199
  self.total_time = 0.0
168
200
  self.last_time = time.time()
201
+ self._visible = False
202
+ self._text = '-fps (-ms)'
203
+
204
+ def set_visible(self, visible):
205
+ if self._visible == visible:
206
+ return
207
+ self._visible = visible
208
+ if visible:
209
+ self.label.configure(text = self._text)
210
+ else:
211
+ self.label.configure(text = '')
169
212
 
170
213
  def __call__(self, t):
171
214
  self.num_iterations += 1
@@ -174,8 +217,77 @@ class FpsLabelUpdater:
174
217
  current_time = time.time()
175
218
  fps = self.num_iterations / (current_time - self.last_time)
176
219
  time_ms = 1000 * self.total_time / self.num_iterations
177
-
178
- self.label.configure(text = '%.1ffps (%dms)' % (fps, time_ms))
220
+ self._text = '%.1ffps (%dms)' % (fps, time_ms)
221
+ if self._visible:
222
+ self.label.configure(text=self._text)
179
223
  self.last_time = current_time
180
224
  self.num_iterations = 0
181
225
  self.total_time = 0.0
226
+
227
+
228
+ class ScrollableFrame(ttk.Frame):
229
+ # From https://blog.teclado.com/tkinter-scrollable-frames/
230
+
231
+ def __init__(self, container, *args, **kwargs):
232
+ super().__init__(container, *args, **kwargs)
233
+ self.header = header = ttk.Frame(self)
234
+ header.pack(anchor="sw")
235
+ self.canvas = canvas = tkinter.Canvas(self)
236
+ self.scrollbar = scrollbar = ttk.Scrollbar(self, orient="vertical",
237
+ command=canvas.yview)
238
+ self.scrollable_frame = ttk.Frame(canvas)
239
+ self.scrollable_frame.bind("<Configure>", self.resize)
240
+ canvas.create_window((0, 0), window=self.scrollable_frame, anchor="nw")
241
+ canvas.configure(yscrollcommand=self.set_scrollbar)
242
+ canvas.pack(side="left", fill="both", expand=True, anchor="nw", pady=10)
243
+ scrollbar.pack(side="right", fill="y", anchor="nw", pady=10)
244
+ scrollbar.is_visible = True
245
+ self.num_columns = 0
246
+ self.has_mouse = False
247
+ self.bind('<Enter>', self.mouse_in)
248
+ self.bind('<Leave>', self.mouse_out)
249
+ self.bind_all('<MouseWheel>', self.mouse_wheel)
250
+
251
+ def headings(self, columninfo):
252
+ for heading, column, weight, span in columninfo:
253
+ self.num_columns = max(self.num_columns, 1 + column)
254
+ self.header.columnconfigure(column, weight=weight)
255
+ self.scrollable_frame.columnconfigure(column, weight=weight)
256
+ ttk.Label(self.header, text=heading).grid(row=0,
257
+ column=column, columnspan=span)
258
+
259
+ def set_widths(self):
260
+ for n in range(self.num_columns):
261
+ header_width = self.header.grid_bbox(n, 0, n, 0)[2]
262
+ column_width = self.scrollable_frame.grid_bbox(n, 0, n, 0)[2]
263
+ width = max(header_width, column_width, 40)
264
+ self.header.columnconfigure(n, minsize=width)
265
+ self.scrollable_frame.columnconfigure(n, minsize=width)
266
+
267
+ def set_scrollbar(self, low, high):
268
+ if float(low) <= 0.0 and float(high) >= 1.0:
269
+ self.scrollbar.pack_forget()
270
+ self.scrollbar.is_visible = False
271
+ else:
272
+ self.scrollbar.pack(side="right", fill="y", anchor="nw", pady=10)
273
+ self.scrollbar.is_visible = True
274
+ self.scrollbar.set(low, high)
275
+
276
+ def resize(self, event=None):
277
+ self.set_widths()
278
+ self.update_idletasks()
279
+ self.canvas.configure(scrollregion=self.canvas.bbox("all"))
280
+
281
+ def mouse_in(self, event=None):
282
+ self.has_mouse = True
283
+
284
+ def mouse_out(self, event=None):
285
+ self.has_mouse = False
286
+
287
+ def mouse_wheel(self, event=None):
288
+ if not self.has_mouse or not self.scrollbar.is_visible:
289
+ return
290
+ low, high = self.scrollbar.get()
291
+ delta = event.delta
292
+ # We might need a scale factor for Windows.
293
+ self.canvas.yview_scroll(-delta, "units")
@@ -1,5 +1,5 @@
1
1
  from .hyperboloid_utilities import *
2
- import math
2
+ from ..matrix import matrix
3
3
  import time
4
4
  import sys
5
5
  import tempfile
@@ -7,55 +7,75 @@ import png
7
7
 
8
8
  __all__ = ['HyperboloidNavigation']
9
9
 
10
+
10
11
  def _move_left(rot_amount, trans_amount):
12
+ RF = trans_amount.parent()
11
13
  return unit_3_vector_and_distance_to_O13_hyperbolic_translation(
12
- [ -1.0, 0.0, 0.0 ], trans_amount) # a
14
+ [ RF(-1), RF(0), RF(0) ], trans_amount) # a
15
+
13
16
 
14
17
  def _move_right(rot_amount, trans_amount):
18
+ RF = trans_amount.parent()
15
19
  return unit_3_vector_and_distance_to_O13_hyperbolic_translation(
16
- [ +1.0, 0.0, 0.0 ], trans_amount) # d
20
+ [ RF(+1), RF(0), RF(0) ], trans_amount) # d
21
+
17
22
 
18
23
  def _move_up(rot_amount, trans_amount):
24
+ RF = trans_amount.parent()
19
25
  return unit_3_vector_and_distance_to_O13_hyperbolic_translation(
20
- [ 0.0, +1.0, 0.0 ], trans_amount) # e
26
+ [ RF(0), RF(+1), RF(0) ], trans_amount) # e
27
+
21
28
 
22
29
  def _move_down(rot_amount, trans_amount):
30
+ RF = trans_amount.parent()
23
31
  return unit_3_vector_and_distance_to_O13_hyperbolic_translation(
24
- [ 0.0, -1.0, 0.0 ], trans_amount) # c
32
+ [ RF(0), RF(-1), RF(0) ], trans_amount) # c
33
+
25
34
 
26
35
  def _move_forward(rot_amount, trans_amount):
36
+ RF = trans_amount.parent()
27
37
  return unit_3_vector_and_distance_to_O13_hyperbolic_translation(
28
- [ 0.0, 0.0, -1.0 ], trans_amount) # w
38
+ [ RF(0), RF(0), RF(-1) ], trans_amount) # w
39
+
29
40
 
30
41
  def _move_backward(rot_amount, trans_amount):
42
+ RF = trans_amount.parent()
31
43
  return unit_3_vector_and_distance_to_O13_hyperbolic_translation(
32
- [ 0.0, 0.0, +1.0 ], trans_amount) # s
44
+ [ RF(0), RF(0), RF(+1) ], trans_amount) # s
45
+
33
46
 
34
47
  def _turn_left(rot_amount, trans_amount):
35
48
  return O13_y_rotation(-rot_amount)
36
49
 
50
+
37
51
  def _turn_right(rot_amount, trans_amount):
38
52
  return O13_y_rotation(rot_amount)
39
53
 
54
+
40
55
  def _turn_up(rot_amount, trans_amount):
41
56
  return O13_x_rotation(-rot_amount)
42
57
 
58
+
43
59
  def _turn_down(rot_amount, trans_amount):
44
60
  return O13_x_rotation(rot_amount)
45
61
 
62
+
46
63
  def _turn_cw(rot_amount, trans_amount): # x
47
64
  return O13_z_rotation(-rot_amount)
48
65
 
66
+
49
67
  def _turn_ccw(rot_amount, trans_amount): # z
50
68
  return O13_z_rotation(rot_amount)
51
69
 
70
+
52
71
  def _add_cursor_keys(d):
53
- d['left'] = _turn_left
72
+ d['left'] = _turn_left
54
73
  d['right'] = _turn_right
55
- d['up'] = _turn_up
56
- d['down'] = _turn_down
74
+ d['up'] = _turn_up
75
+ d['down'] = _turn_down
57
76
  return d
58
77
 
78
+
59
79
  _keymappings = {
60
80
  'QWERTY' : _add_cursor_keys(
61
81
  { 'a' : _move_left,
@@ -117,6 +137,7 @@ _ignore_key_release_time_s = 0.005
117
137
 
118
138
  _viewModes = [ 'Weight', 'Distance', 'Tet Num' ]
119
139
 
140
+
120
141
  class HyperboloidNavigation:
121
142
  """
122
143
  A mixin class for a Tk widget that binds some key and mouse events
@@ -124,17 +145,18 @@ class HyperboloidNavigation:
124
145
 
125
146
  This is a mixin class and some other class in the class hierarchy
126
147
  is expected to provide the following attributes and methods:
127
- - self.raytracing_data has to be an instance of, e.g.,
128
- IdealRaytracingData. This is needed to update data
129
- such as the view matrix
130
- using self.raytracing_data.update_view_state(...).
131
- - self.redraw_if_initialized() to redraw.
132
- - self.read_depth_value(x, y) to return the depth value at a pixel.
133
- It is used for orbiting about that point.
134
- - self.compute_translation_and_inverse_from_pick_point(size, xy, depth)
135
- returning the SO(1,3)-matrices for conjugating to orbit with a certain
136
- speed about the point with frag coord xy and depth given a viewport of
137
- size size.
148
+
149
+ - self.raytracing_data has to be an instance of, e.g.,
150
+ IdealRaytracingData. This is needed to update data
151
+ such as the view matrix
152
+ using self.raytracing_data.update_view_state(...).
153
+ - self.draw() to redraw.
154
+ - self.read_depth_value(x, y) to return the depth value at a pixel.
155
+ It is used for orbiting about that point.
156
+ - self.compute_translation_and_inverse_from_pick_point(size, xy, depth)
157
+ returning the SO(1,3)-matrices for conjugating to orbit with a certain
158
+ speed about the point with frag coord xy and depth given a viewport of
159
+ size size.
138
160
 
139
161
  The mixin class will provide the attribute self.view_state (e.g.,
140
162
  pair of view matrix and tetrahedron we are in).
@@ -164,7 +186,7 @@ class HyperboloidNavigation:
164
186
  self.view_state = self.raytracing_data.initial_view_state()
165
187
 
166
188
  self.cursor = _default_cursor
167
- self.configure(cursor = self.cursor)
189
+ self.configure(cursor=self.cursor)
168
190
 
169
191
  # Parameters controlling navigation in the same format that
170
192
  # get_uniform_binding returns..
@@ -230,10 +252,7 @@ class HyperboloidNavigation:
230
252
  t = time.time()
231
253
 
232
254
  # Compute the matrix to update the view
233
- m = matrix([[1.0,0.0,0.0,0.0],
234
- [0.0,1.0,0.0,0.0],
235
- [0.0,0.0,1.0,0.0],
236
- [0.0,0.0,0.0,1.0]])
255
+ m = matrix.identity(self.raytracing_data.RF, 4)
237
256
 
238
257
  # Is there any key event that needs processing so we need to
239
258
  # redraw.
@@ -282,11 +301,12 @@ class HyperboloidNavigation:
282
301
  last_and_release[0] = t
283
302
 
284
303
  # If there is key press time we need to account for
285
- if not dT is None:
304
+ if dT is not None:
305
+ RF = m.base_ring()
286
306
  # Compute effect on view matrix
287
307
  m = m * self.keymapping[k](
288
- dT * self.navigation_dict['rotationVelocity'][1],
289
- dT * self.navigation_dict['translationVelocity'][1])
308
+ RF(dT * self.navigation_dict['rotationVelocity'][1]),
309
+ RF(dT * self.navigation_dict['translationVelocity'][1]))
290
310
  any_key = True
291
311
 
292
312
  if not any_key:
@@ -298,7 +318,7 @@ class HyperboloidNavigation:
298
318
  self.view_state, m)
299
319
 
300
320
  # Redraw
301
- self.redraw_if_initialized()
321
+ self.draw()
302
322
 
303
323
  # And schedule another call of this function.
304
324
  # If we don't leave Tk a couple of milliseconds in between,
@@ -319,7 +339,7 @@ class HyperboloidNavigation:
319
339
  self.cursor = _default_cursor
320
340
 
321
341
  if not self.mouse_mode:
322
- self.configure(cursor = self.cursor)
342
+ self.configure(cursor=self.cursor)
323
343
 
324
344
  def tkKeyPress(self, event):
325
345
  if self.mouse_mode:
@@ -330,7 +350,7 @@ class HyperboloidNavigation:
330
350
 
331
351
  cursor = _cursor_mappings.get(k)
332
352
  if cursor:
333
- self.configure(cursor = cursor)
353
+ self.configure(cursor=cursor)
334
354
 
335
355
  last_and_release = self.key_to_last_accounted_and_release_time.get(k)
336
356
  if last_and_release:
@@ -364,7 +384,7 @@ class HyperboloidNavigation:
364
384
  self.view = (self.view + 1) % 3
365
385
  print("Color for rays that have not hit geometry:",
366
386
  _viewModes[self.view])
367
- self.redraw_if_initialized()
387
+ self.draw()
368
388
 
369
389
  if event.keysym == 'p':
370
390
  from snappy.CyOpenGL import get_gl_string
@@ -382,9 +402,9 @@ class HyperboloidNavigation:
382
402
 
383
403
  width = 1000
384
404
  height = 1000
385
-
405
+
386
406
  f = tempfile.NamedTemporaryFile(
387
- suffix = '.png', delete = False)
407
+ suffix='.png', delete=False)
388
408
 
389
409
  self.save_image(width, height, f)
390
410
 
@@ -397,7 +417,7 @@ class HyperboloidNavigation:
397
417
  if last or release:
398
418
  return
399
419
 
400
- self.configure(cursor = _default_move_cursor)
420
+ self.configure(cursor=_default_move_cursor)
401
421
 
402
422
  self.mouse_pos_when_pressed = (event.x, event.y)
403
423
  self.view_state_when_pressed = self.view_state
@@ -432,10 +452,7 @@ class HyperboloidNavigation:
432
452
  self.last_mouse_pos = (event.x, event.y)
433
453
  self.view_state_when_pressed = self.view_state
434
454
 
435
- self.orbit_rotation = matrix([[1.0,0.0,0.0,0.0],
436
- [0.0,1.0,0.0,0.0],
437
- [0.0,0.0,1.0,0.0],
438
- [0.0,0.0,0.0,1.0]])
455
+ self.orbit_rotation = matrix.identity(self.raytracing_data.RF, 4)
439
456
 
440
457
  self.mouse_mode = 'orbit'
441
458
 
@@ -444,8 +461,10 @@ class HyperboloidNavigation:
444
461
  delta_x = event.x - self.last_mouse_pos[0]
445
462
  delta_y = event.y - self.last_mouse_pos[1]
446
463
 
447
- angle_x = delta_x * self.orbit_speed * 0.01
448
- angle_y = delta_y * self.orbit_speed * 0.01
464
+ RF = self.raytracing_data.RF
465
+
466
+ angle_x = RF(delta_x * self.orbit_speed * 0.01)
467
+ angle_y = RF(delta_y * self.orbit_speed * 0.01)
449
468
 
450
469
  m = O13_y_rotation(angle_x) * O13_x_rotation(angle_y)
451
470
  self.orbit_rotation = self.orbit_rotation * m
@@ -456,24 +475,31 @@ class HyperboloidNavigation:
456
475
 
457
476
  self.last_mouse_pos = (event.x, event.y)
458
477
  elif self.mouse_mode == 'move':
459
- delta_x = event.x - self.mouse_pos_when_pressed[0]
460
- delta_y = event.y - self.mouse_pos_when_pressed[1]
478
+ RF = self.raytracing_data.RF
479
+
480
+ delta_x = RF(event.x - self.mouse_pos_when_pressed[0])
481
+ delta_y = RF(event.y - self.mouse_pos_when_pressed[1])
461
482
 
462
- amt = math.sqrt(delta_x ** 2 + delta_y ** 2)
483
+ amt = (delta_x ** 2 + delta_y ** 2).sqrt()
463
484
 
464
485
  if amt == 0:
465
486
  self.view_state = self.view_state_when_pressed
466
487
  else:
467
488
  m = unit_3_vector_and_distance_to_O13_hyperbolic_translation(
468
- [-delta_x / amt, delta_y / amt, 0.0], amt * 0.01)
489
+ [-delta_x / amt, delta_y / amt, RF(0)], amt * RF(0.01))
469
490
 
470
491
  self.view_state = self.raytracing_data.update_view_state(
471
492
  self.view_state_when_pressed, m)
472
493
  elif self.mouse_mode == 'rotate':
494
+ RF = self.raytracing_data.RF
495
+
473
496
  delta_x = event.x - self.mouse_pos_when_pressed[0]
474
497
  delta_y = event.y - self.mouse_pos_when_pressed[1]
475
498
 
476
- m = O13_y_rotation(-delta_x * 0.01) * O13_x_rotation(-delta_y * 0.01)
499
+ angle_x = RF(-delta_x * 0.01)
500
+ angle_y = RF(-delta_y * 0.01)
501
+
502
+ m = O13_y_rotation(angle_x) * O13_x_rotation(angle_y)
477
503
 
478
504
  self.view_state = self.raytracing_data.update_view_state(
479
505
  self.view_state, m)
@@ -482,13 +508,13 @@ class HyperboloidNavigation:
482
508
  else:
483
509
  return
484
510
 
485
- self.redraw_if_initialized()
511
+ self.draw()
486
512
 
487
513
  def tkButtonRelease1(self, event):
488
514
  self.mouse_mode = None
489
- self.configure(cursor = self.cursor)
515
+ self.configure(cursor=self.cursor)
490
516
 
491
- def setup_keymapping(self, keyboard = 'QWERTY'):
517
+ def setup_keymapping(self, keyboard='QWERTY'):
492
518
  self.keymapping = _keymappings[keyboard]
493
519
 
494
520
  # Key (e.g., 'w', 'a', ...) to pair of time stamps.
@@ -502,5 +528,29 @@ class HyperboloidNavigation:
502
528
  for k in self.keymapping
503
529
  }
504
530
 
505
- def apply_prefs(self, prefs):
506
- self.setup_keymapping(prefs.get('keyboard', 'QWERTY'))
531
+ def apply_settings(self, settings):
532
+ self.setup_keymapping(settings.get('keyboard', 'QWERTY'))
533
+
534
+ def _start_flight_for_debugging_hitch(self):
535
+ """
536
+ On Mac OS, there is a hitch when flying. It is subtle, but when
537
+ keeping, say the w key pressed, every second or so there a brief
538
+ moment where we are not moving.
539
+
540
+ I couldn't figure out whether this is due to how we are processing
541
+ the key events or already a problem with calling self.after from
542
+ within the redraw code.
543
+
544
+ This function initiates a flight to isolate the problem to the
545
+ latter.
546
+
547
+ To use it, do:
548
+ >>> M = Manifold("m004") # doctest: +SKIP
549
+ >>> v = M.inside_view()
550
+ >>> v.view.widget._start_flight_for_debugging_hitch()
551
+
552
+ """
553
+
554
+ self.key_to_last_accounted_and_release_time['w'][0] = time.time()
555
+ self.schedule_process_key_events_and_redraw(1)
556
+