snappy 3.2__cp310-cp310-macosx_10_12_x86_64.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (503) hide show
  1. snappy/CyOpenGL.cpython-310-darwin.so +0 -0
  2. snappy/SnapPy.cpython-310-darwin.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-310-darwin.so +0 -0
  6. snappy/__init__.py +760 -0
  7. snappy/app.py +605 -0
  8. snappy/app_menus.py +372 -0
  9. snappy/browser.py +998 -0
  10. snappy/cache.py +25 -0
  11. snappy/canonical.py +249 -0
  12. snappy/cusps/__init__.py +38 -0
  13. snappy/cusps/cusp_area_matrix.py +101 -0
  14. snappy/cusps/cusp_areas_from_matrix.py +173 -0
  15. snappy/cusps/maximal_cusp_area_matrix.py +136 -0
  16. snappy/cusps/test.py +21 -0
  17. snappy/cusps/trig_cusp_area_matrix.py +63 -0
  18. snappy/database.py +454 -0
  19. snappy/db_utilities.py +79 -0
  20. snappy/decorated_isosig.py +710 -0
  21. snappy/dev/__init__.py +0 -0
  22. snappy/dev/extended_ptolemy/__init__.py +8 -0
  23. snappy/dev/extended_ptolemy/closed.py +106 -0
  24. snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
  25. snappy/dev/extended_ptolemy/direct.py +42 -0
  26. snappy/dev/extended_ptolemy/extended.py +406 -0
  27. snappy/dev/extended_ptolemy/giac_helper.py +43 -0
  28. snappy/dev/extended_ptolemy/giac_rur.py +129 -0
  29. snappy/dev/extended_ptolemy/gluing.py +46 -0
  30. snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
  31. snappy/dev/extended_ptolemy/printMatrices.py +70 -0
  32. snappy/dev/vericlosed/__init__.py +1 -0
  33. snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
  34. snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
  35. snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
  36. snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
  37. snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
  38. snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
  39. snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
  40. snappy/dev/vericlosed/orb/__init__.py +1 -0
  41. snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
  42. snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
  43. snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
  44. snappy/dev/vericlosed/test.py +54 -0
  45. snappy/dev/vericlosed/truncatedComplex.py +176 -0
  46. snappy/dev/vericlosed/verificationError.py +58 -0
  47. snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
  48. snappy/doc/_images/SnapPy-196.png +0 -0
  49. snappy/doc/_images/geodesics.jpg +0 -0
  50. snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
  51. snappy/doc/_images/m125_paper_plane.jpg +0 -0
  52. snappy/doc/_images/mac.png +0 -0
  53. snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
  54. snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
  55. snappy/doc/_images/plink-action.png +0 -0
  56. snappy/doc/_images/ubuntu.png +0 -0
  57. snappy/doc/_images/win7.png +0 -0
  58. snappy/doc/_sources/additional_classes.rst.txt +40 -0
  59. snappy/doc/_sources/bugs.rst.txt +14 -0
  60. snappy/doc/_sources/censuses.rst.txt +51 -0
  61. snappy/doc/_sources/credits.rst.txt +75 -0
  62. snappy/doc/_sources/development.rst.txt +259 -0
  63. snappy/doc/_sources/index.rst.txt +182 -0
  64. snappy/doc/_sources/installing.rst.txt +247 -0
  65. snappy/doc/_sources/manifold.rst.txt +6 -0
  66. snappy/doc/_sources/manifoldhp.rst.txt +46 -0
  67. snappy/doc/_sources/news.rst.txt +355 -0
  68. snappy/doc/_sources/other.rst.txt +25 -0
  69. snappy/doc/_sources/platonic_census.rst.txt +20 -0
  70. snappy/doc/_sources/plink.rst.txt +102 -0
  71. snappy/doc/_sources/ptolemy.rst.txt +66 -0
  72. snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
  73. snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
  74. snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
  75. snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
  76. snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
  77. snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
  78. snappy/doc/_sources/screenshots.rst.txt +21 -0
  79. snappy/doc/_sources/snap.rst.txt +87 -0
  80. snappy/doc/_sources/snappy.rst.txt +28 -0
  81. snappy/doc/_sources/spherogram.rst.txt +103 -0
  82. snappy/doc/_sources/todo.rst.txt +47 -0
  83. snappy/doc/_sources/triangulation.rst.txt +11 -0
  84. snappy/doc/_sources/tutorial.rst.txt +49 -0
  85. snappy/doc/_sources/verify.rst.txt +210 -0
  86. snappy/doc/_sources/verify_internals.rst.txt +79 -0
  87. snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
  88. snappy/doc/_static/SnapPy.ico +0 -0
  89. snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
  90. snappy/doc/_static/basic.css +925 -0
  91. snappy/doc/_static/css/badge_only.css +1 -0
  92. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
  93. snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
  94. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
  95. snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
  96. snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
  97. snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
  98. snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
  99. snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
  100. snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
  101. snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
  102. snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
  103. snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
  104. snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
  105. snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
  106. snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
  107. snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
  108. snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
  109. snappy/doc/_static/css/theme.css +4 -0
  110. snappy/doc/_static/doctools.js +156 -0
  111. snappy/doc/_static/documentation_options.js +13 -0
  112. snappy/doc/_static/file.png +0 -0
  113. snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
  114. snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
  115. snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
  116. snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
  117. snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
  118. snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
  119. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
  120. snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
  121. snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
  122. snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
  123. snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
  124. snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
  125. snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
  126. snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
  127. snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
  128. snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
  129. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
  130. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
  131. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
  132. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
  133. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
  134. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
  135. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
  136. snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
  137. snappy/doc/_static/jquery.js +2 -0
  138. snappy/doc/_static/js/badge_only.js +1 -0
  139. snappy/doc/_static/js/theme.js +1 -0
  140. snappy/doc/_static/js/versions.js +228 -0
  141. snappy/doc/_static/language_data.js +199 -0
  142. snappy/doc/_static/minus.png +0 -0
  143. snappy/doc/_static/plus.png +0 -0
  144. snappy/doc/_static/pygments.css +75 -0
  145. snappy/doc/_static/searchtools.js +620 -0
  146. snappy/doc/_static/snappy_furo.css +33 -0
  147. snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
  148. snappy/doc/_static/sphinx_highlight.js +154 -0
  149. snappy/doc/additional_classes.html +1500 -0
  150. snappy/doc/bugs.html +132 -0
  151. snappy/doc/censuses.html +427 -0
  152. snappy/doc/credits.html +181 -0
  153. snappy/doc/development.html +384 -0
  154. snappy/doc/genindex.html +1331 -0
  155. snappy/doc/index.html +262 -0
  156. snappy/doc/installing.html +346 -0
  157. snappy/doc/manifold.html +3452 -0
  158. snappy/doc/manifoldhp.html +180 -0
  159. snappy/doc/news.html +388 -0
  160. snappy/doc/objects.inv +0 -0
  161. snappy/doc/other.html +161 -0
  162. snappy/doc/platonic_census.html +375 -0
  163. snappy/doc/plink.html +210 -0
  164. snappy/doc/ptolemy.html +254 -0
  165. snappy/doc/ptolemy_classes.html +1144 -0
  166. snappy/doc/ptolemy_examples1.html +409 -0
  167. snappy/doc/ptolemy_examples2.html +471 -0
  168. snappy/doc/ptolemy_examples3.html +414 -0
  169. snappy/doc/ptolemy_examples4.html +195 -0
  170. snappy/doc/ptolemy_prelim.html +248 -0
  171. snappy/doc/py-modindex.html +165 -0
  172. snappy/doc/screenshots.html +141 -0
  173. snappy/doc/search.html +135 -0
  174. snappy/doc/searchindex.js +1 -0
  175. snappy/doc/snap.html +202 -0
  176. snappy/doc/snappy.html +181 -0
  177. snappy/doc/spherogram.html +1211 -0
  178. snappy/doc/todo.html +166 -0
  179. snappy/doc/triangulation.html +1584 -0
  180. snappy/doc/tutorial.html +159 -0
  181. snappy/doc/verify.html +330 -0
  182. snappy/doc/verify_internals.html +1235 -0
  183. snappy/drilling/__init__.py +456 -0
  184. snappy/drilling/barycentric.py +103 -0
  185. snappy/drilling/constants.py +5 -0
  186. snappy/drilling/crush.py +270 -0
  187. snappy/drilling/cusps.py +125 -0
  188. snappy/drilling/debug.py +242 -0
  189. snappy/drilling/epsilons.py +6 -0
  190. snappy/drilling/exceptions.py +55 -0
  191. snappy/drilling/moves.py +620 -0
  192. snappy/drilling/peripheral_curves.py +210 -0
  193. snappy/drilling/perturb.py +188 -0
  194. snappy/drilling/shorten.py +36 -0
  195. snappy/drilling/subdivide.py +274 -0
  196. snappy/drilling/test.py +23 -0
  197. snappy/drilling/test_cases.py +126 -0
  198. snappy/drilling/tracing.py +351 -0
  199. snappy/exceptions.py +26 -0
  200. snappy/export_stl.py +120 -0
  201. snappy/exterior_to_link/__init__.py +2 -0
  202. snappy/exterior_to_link/barycentric_geometry.py +463 -0
  203. snappy/exterior_to_link/exceptions.py +6 -0
  204. snappy/exterior_to_link/geodesic_map.json +14408 -0
  205. snappy/exterior_to_link/hyp_utils.py +112 -0
  206. snappy/exterior_to_link/link_projection.py +323 -0
  207. snappy/exterior_to_link/main.py +197 -0
  208. snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
  209. snappy/exterior_to_link/mcomplex_with_link.py +687 -0
  210. snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
  211. snappy/exterior_to_link/pl_utils.py +491 -0
  212. snappy/exterior_to_link/put_in_S3.py +156 -0
  213. snappy/exterior_to_link/rational_linear_algebra.py +123 -0
  214. snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
  215. snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
  216. snappy/exterior_to_link/stored_moves.py +475 -0
  217. snappy/exterior_to_link/test.py +31 -0
  218. snappy/filedialog.py +28 -0
  219. snappy/geometric_structure/__init__.py +212 -0
  220. snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
  221. snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +697 -0
  222. snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +484 -0
  223. snappy/geometric_structure/cusp_neighborhood/exceptions.py +42 -0
  224. snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +298 -0
  225. snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +159 -0
  226. snappy/geometric_structure/cusp_neighborhood/vertices.py +32 -0
  227. snappy/geometric_structure/geodesic/__init__.py +0 -0
  228. snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
  229. snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
  230. snappy/geometric_structure/geodesic/canonical_keys.py +52 -0
  231. snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
  232. snappy/geometric_structure/geodesic/constants.py +6 -0
  233. snappy/geometric_structure/geodesic/exceptions.py +22 -0
  234. snappy/geometric_structure/geodesic/fixed_points.py +93 -0
  235. snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
  236. snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
  237. snappy/geometric_structure/geodesic/line.py +30 -0
  238. snappy/geometric_structure/geodesic/multiplicity.py +127 -0
  239. snappy/geometric_structure/geodesic/tiles_for_geodesic.py +101 -0
  240. snappy/geometric_structure/test.py +22 -0
  241. snappy/gui.py +121 -0
  242. snappy/horoviewer.py +443 -0
  243. snappy/hyperboloid/__init__.py +212 -0
  244. snappy/hyperboloid/distances.py +245 -0
  245. snappy/hyperboloid/horoball.py +19 -0
  246. snappy/hyperboloid/line.py +35 -0
  247. snappy/hyperboloid/point.py +9 -0
  248. snappy/hyperboloid/triangle.py +29 -0
  249. snappy/info_icon.gif +0 -0
  250. snappy/infowindow.py +65 -0
  251. snappy/isometry_signature.py +382 -0
  252. snappy/len_spec/__init__.py +596 -0
  253. snappy/len_spec/geodesic_info.py +110 -0
  254. snappy/len_spec/geodesic_key_info_dict.py +117 -0
  255. snappy/len_spec/geodesic_piece.py +143 -0
  256. snappy/len_spec/geometric_structure.py +182 -0
  257. snappy/len_spec/geometry.py +80 -0
  258. snappy/len_spec/length_spectrum_geodesic_info.py +170 -0
  259. snappy/len_spec/spine.py +206 -0
  260. snappy/len_spec/test.py +24 -0
  261. snappy/len_spec/test_cases.py +69 -0
  262. snappy/len_spec/tile.py +275 -0
  263. snappy/len_spec/word.py +86 -0
  264. snappy/manifolds/HTWKnots/alternating.gz +0 -0
  265. snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
  266. snappy/manifolds/__init__.py +3 -0
  267. snappy/math_basics.py +176 -0
  268. snappy/matrix.py +525 -0
  269. snappy/number.py +657 -0
  270. snappy/numeric_output_checker.py +345 -0
  271. snappy/pari.py +41 -0
  272. snappy/phone_home.py +57 -0
  273. snappy/polyviewer.py +259 -0
  274. snappy/ptolemy/__init__.py +17 -0
  275. snappy/ptolemy/component.py +103 -0
  276. snappy/ptolemy/coordinates.py +2290 -0
  277. snappy/ptolemy/fieldExtensions.py +153 -0
  278. snappy/ptolemy/findLoops.py +473 -0
  279. snappy/ptolemy/geometricRep.py +59 -0
  280. snappy/ptolemy/homology.py +165 -0
  281. snappy/ptolemy/magma/default.magma_template +229 -0
  282. snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
  283. snappy/ptolemy/manifoldMethods.py +395 -0
  284. snappy/ptolemy/matrix.py +350 -0
  285. snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
  286. snappy/ptolemy/polynomial.py +857 -0
  287. snappy/ptolemy/processComponents.py +173 -0
  288. snappy/ptolemy/processFileBase.py +247 -0
  289. snappy/ptolemy/processFileDispatch.py +46 -0
  290. snappy/ptolemy/processMagmaFile.py +392 -0
  291. snappy/ptolemy/processRurFile.py +150 -0
  292. snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
  293. snappy/ptolemy/ptolemyObstructionClass.py +64 -0
  294. snappy/ptolemy/ptolemyVariety.py +1029 -0
  295. snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
  296. snappy/ptolemy/reginaWrapper.py +698 -0
  297. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  298. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  299. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  300. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  301. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  302. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  303. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  304. snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  305. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  306. snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  307. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
  308. snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  309. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  310. snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
  311. snappy/ptolemy/rur.py +545 -0
  312. snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
  313. snappy/ptolemy/test.py +1126 -0
  314. snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
  315. snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
  316. snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
  317. snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
  318. snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
  319. snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
  320. snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
  321. snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
  322. snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
  323. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
  324. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
  325. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
  326. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
  327. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
  328. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
  329. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
  330. snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
  331. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
  332. snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
  333. snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
  334. snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
  335. snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
  336. snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
  337. snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
  338. snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
  339. snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
  340. snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
  341. snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
  342. snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
  343. snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
  344. snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
  345. snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
  346. snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
  347. snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
  348. snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
  349. snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
  350. snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
  351. snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
  352. snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
  353. snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
  354. snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
  355. snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
  356. snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
  357. snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
  358. snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
  359. snappy/ptolemy/utilities.py +236 -0
  360. snappy/raytracing/__init__.py +64 -0
  361. snappy/raytracing/additional_horospheres.py +64 -0
  362. snappy/raytracing/additional_len_spec_choices.py +63 -0
  363. snappy/raytracing/cohomology_fractal.py +197 -0
  364. snappy/raytracing/eyeball.py +123 -0
  365. snappy/raytracing/finite_raytracing_data.py +237 -0
  366. snappy/raytracing/finite_viewer.py +590 -0
  367. snappy/raytracing/geodesic_tube_info.py +174 -0
  368. snappy/raytracing/geodesics.py +246 -0
  369. snappy/raytracing/geodesics_window.py +258 -0
  370. snappy/raytracing/gui_utilities.py +293 -0
  371. snappy/raytracing/hyperboloid_navigation.py +556 -0
  372. snappy/raytracing/hyperboloid_utilities.py +234 -0
  373. snappy/raytracing/ideal_raytracing_data.py +592 -0
  374. snappy/raytracing/inside_viewer.py +974 -0
  375. snappy/raytracing/pack.py +22 -0
  376. snappy/raytracing/raytracing_data.py +126 -0
  377. snappy/raytracing/raytracing_view.py +454 -0
  378. snappy/raytracing/shaders/Eye.png +0 -0
  379. snappy/raytracing/shaders/NonGeometric.png +0 -0
  380. snappy/raytracing/shaders/__init__.py +101 -0
  381. snappy/raytracing/shaders/fragment.glsl +1744 -0
  382. snappy/raytracing/test.py +29 -0
  383. snappy/raytracing/tooltip.py +146 -0
  384. snappy/raytracing/upper_halfspace_utilities.py +98 -0
  385. snappy/raytracing/view_scale_controller.py +98 -0
  386. snappy/raytracing/zoom_slider/__init__.py +263 -0
  387. snappy/raytracing/zoom_slider/inward.png +0 -0
  388. snappy/raytracing/zoom_slider/inward18.png +0 -0
  389. snappy/raytracing/zoom_slider/outward.png +0 -0
  390. snappy/raytracing/zoom_slider/outward18.png +0 -0
  391. snappy/raytracing/zoom_slider/test.py +20 -0
  392. snappy/sage_helper.py +117 -0
  393. snappy/settings.py +409 -0
  394. snappy/shell.py +53 -0
  395. snappy/snap/__init__.py +114 -0
  396. snappy/snap/character_varieties.py +375 -0
  397. snappy/snap/find_field.py +372 -0
  398. snappy/snap/fundamental_polyhedron.py +569 -0
  399. snappy/snap/generators.py +39 -0
  400. snappy/snap/interval_reps.py +81 -0
  401. snappy/snap/kernel_structures.py +128 -0
  402. snappy/snap/mcomplex_base.py +18 -0
  403. snappy/snap/nsagetools.py +702 -0
  404. snappy/snap/peripheral/__init__.py +1 -0
  405. snappy/snap/peripheral/dual_cellulation.py +219 -0
  406. snappy/snap/peripheral/link.py +127 -0
  407. snappy/snap/peripheral/peripheral.py +159 -0
  408. snappy/snap/peripheral/surface.py +522 -0
  409. snappy/snap/peripheral/test.py +35 -0
  410. snappy/snap/polished_reps.py +335 -0
  411. snappy/snap/shapes.py +152 -0
  412. snappy/snap/slice_obs_HKL.py +668 -0
  413. snappy/snap/t3mlite/__init__.py +2 -0
  414. snappy/snap/t3mlite/arrow.py +243 -0
  415. snappy/snap/t3mlite/corner.py +22 -0
  416. snappy/snap/t3mlite/edge.py +172 -0
  417. snappy/snap/t3mlite/face.py +37 -0
  418. snappy/snap/t3mlite/files.py +211 -0
  419. snappy/snap/t3mlite/homology.py +53 -0
  420. snappy/snap/t3mlite/linalg.py +419 -0
  421. snappy/snap/t3mlite/mcomplex.py +1499 -0
  422. snappy/snap/t3mlite/perm4.py +320 -0
  423. snappy/snap/t3mlite/setup.py +12 -0
  424. snappy/snap/t3mlite/simplex.py +199 -0
  425. snappy/snap/t3mlite/spun.py +297 -0
  426. snappy/snap/t3mlite/surface.py +519 -0
  427. snappy/snap/t3mlite/test.py +20 -0
  428. snappy/snap/t3mlite/test_vs_regina.py +86 -0
  429. snappy/snap/t3mlite/tetrahedron.py +109 -0
  430. snappy/snap/t3mlite/vertex.py +42 -0
  431. snappy/snap/test.py +134 -0
  432. snappy/snap/utilities.py +288 -0
  433. snappy/test.py +209 -0
  434. snappy/test_cases.py +263 -0
  435. snappy/testing.py +131 -0
  436. snappy/tiling/__init__.py +2 -0
  437. snappy/tiling/canonical_key_dict.py +59 -0
  438. snappy/tiling/dict_based_set.py +79 -0
  439. snappy/tiling/floor.py +49 -0
  440. snappy/tiling/hyperboloid_dict.py +54 -0
  441. snappy/tiling/iter_utils.py +78 -0
  442. snappy/tiling/lifted_tetrahedron.py +22 -0
  443. snappy/tiling/lifted_tetrahedron_set.py +54 -0
  444. snappy/tiling/real_hash_dict.py +164 -0
  445. snappy/tiling/test.py +23 -0
  446. snappy/tiling/tile.py +215 -0
  447. snappy/tiling/triangle.py +33 -0
  448. snappy/tkterminal.py +920 -0
  449. snappy/twister/__init__.py +20 -0
  450. snappy/twister/main.py +646 -0
  451. snappy/twister/surfaces/S_0_1 +3 -0
  452. snappy/twister/surfaces/S_0_2 +3 -0
  453. snappy/twister/surfaces/S_0_4 +7 -0
  454. snappy/twister/surfaces/S_0_4_Lantern +8 -0
  455. snappy/twister/surfaces/S_1 +3 -0
  456. snappy/twister/surfaces/S_1_1 +4 -0
  457. snappy/twister/surfaces/S_1_2 +5 -0
  458. snappy/twister/surfaces/S_1_2_5 +6 -0
  459. snappy/twister/surfaces/S_2 +6 -0
  460. snappy/twister/surfaces/S_2_1 +8 -0
  461. snappy/twister/surfaces/S_2_heeg +10 -0
  462. snappy/twister/surfaces/S_3 +8 -0
  463. snappy/twister/surfaces/S_3_1 +10 -0
  464. snappy/twister/surfaces/S_4_1 +12 -0
  465. snappy/twister/surfaces/S_5_1 +14 -0
  466. snappy/twister/surfaces/heeg_fig8 +9 -0
  467. snappy/twister/twister_core.cpython-310-darwin.so +0 -0
  468. snappy/upper_halfspace/__init__.py +146 -0
  469. snappy/upper_halfspace/ideal_point.py +26 -0
  470. snappy/verify/__init__.py +13 -0
  471. snappy/verify/canonical.py +542 -0
  472. snappy/verify/complex_volume/__init__.py +18 -0
  473. snappy/verify/complex_volume/adjust_torsion.py +86 -0
  474. snappy/verify/complex_volume/closed.py +168 -0
  475. snappy/verify/complex_volume/compute_ptolemys.py +90 -0
  476. snappy/verify/complex_volume/cusped.py +56 -0
  477. snappy/verify/complex_volume/extended_bloch.py +201 -0
  478. snappy/verify/cusp_translations.py +85 -0
  479. snappy/verify/edge_equations.py +80 -0
  480. snappy/verify/exceptions.py +254 -0
  481. snappy/verify/hyperbolicity.py +224 -0
  482. snappy/verify/interval_newton_shapes_engine.py +523 -0
  483. snappy/verify/interval_tree.py +400 -0
  484. snappy/verify/krawczyk_shapes_engine.py +518 -0
  485. snappy/verify/maximal_cusp_area_matrix/__init__.py +46 -0
  486. snappy/verify/maximal_cusp_area_matrix/cusp_tiling_engine.py +419 -0
  487. snappy/verify/maximal_cusp_area_matrix/cusp_translate_engine.py +153 -0
  488. snappy/verify/real_algebra.py +286 -0
  489. snappy/verify/shapes.py +25 -0
  490. snappy/verify/short_slopes.py +200 -0
  491. snappy/verify/square_extensions.py +1005 -0
  492. snappy/verify/test.py +78 -0
  493. snappy/verify/upper_halfspace/__init__.py +9 -0
  494. snappy/verify/upper_halfspace/extended_matrix.py +100 -0
  495. snappy/verify/upper_halfspace/finite_point.py +283 -0
  496. snappy/verify/upper_halfspace/ideal_point.py +426 -0
  497. snappy/verify/volume.py +128 -0
  498. snappy/version.py +2 -0
  499. snappy-3.2.dist-info/METADATA +58 -0
  500. snappy-3.2.dist-info/RECORD +503 -0
  501. snappy-3.2.dist-info/WHEEL +5 -0
  502. snappy-3.2.dist-info/entry_points.txt +2 -0
  503. snappy-3.2.dist-info/top_level.txt +28 -0
snappy/browser.py ADDED
@@ -0,0 +1,998 @@
1
+ # -*- coding: utf-8 -*-
2
+ import sys
3
+ import os
4
+ from .gui import *
5
+ from .polyviewer import PolyhedronViewer
6
+ from .horoviewer import HoroballViewer
7
+ from .CyOpenGL import GetColor
8
+ from .app_menus import browser_menus
9
+ from . import app_menus
10
+ from .number import Number
11
+ from . import database
12
+ from .exceptions import SnapPeaFatalError
13
+ from plink import LinkViewer, LinkEditor
14
+ from plink.ipython_tools import IPythonTkRoot
15
+ from spherogram.links.orthogonal import OrthogonalLinkDiagram
16
+ try:
17
+ from tkinter.simpledialog import _place_window
18
+ except:
19
+ pass
20
+
21
+
22
+ main_window = None
23
+ # TODO: Find these dimensions by introspection.
24
+ cusp_box_height = 105
25
+ if sys.platform == 'darwin':
26
+ cusp_box_width = 180
27
+ elif sys.platform == 'win32':
28
+ cusp_box_width = 150
29
+ else:
30
+ cusp_box_width = 210
31
+
32
+
33
+ class SelectableText(ttk.Frame):
34
+ """
35
+ A Label and a disabled Entry widget which is disguised as a label
36
+ but, unlike a Label, allows selecting the text. On the Mac, the
37
+ background color matches the background of a depth 2 LabelFrame
38
+ by default.
39
+ """
40
+ def __init__(self, container, labeltext='', width=18, depth=2):
41
+ ttk.Frame.__init__(self, container)
42
+ self.var = Tk_.StringVar(container)
43
+ style = SnapPyStyle()
44
+ bg_color = style.groupBG if depth == 1 else style.subgroupBG
45
+ self.label = label = ttk.Label(self, text=labeltext)
46
+ self.value = value = Tk_.Entry(self, textvariable=self.var,
47
+ state='readonly', borderwidth=0, readonlybackground=bg_color,
48
+ highlightbackground=bg_color, highlightcolor=bg_color,
49
+ highlightthickness=0, takefocus=False)
50
+ if width:
51
+ value.config(width=width)
52
+ label.pack(side=Tk_.LEFT)
53
+ value.pack(side=Tk_.LEFT, padx=2)
54
+
55
+ def set(self, value):
56
+ self.var.set(value)
57
+ self.value.selection_clear()
58
+
59
+ def get(self):
60
+ return self.var.get()
61
+
62
+
63
+ class AutoScrollbar(Tk_.Scrollbar):
64
+ # Frederick Lundh's scrollbar that hides itself if it's not needed.
65
+ def set(self, lo, hi):
66
+ if float(lo) <= 0.0 and float(hi) >= 1.0:
67
+ self.grid_remove()
68
+ else:
69
+ self.grid()
70
+ Tk_.Scrollbar.set(self, lo, hi)
71
+
72
+
73
+ class SelectableMessage(ttk.Frame):
74
+ """
75
+ A disabled Text widget which allows selection of text. On the mac
76
+ the selection does not highlight correctly unless the Text widget has
77
+ focus and does not clear correctly unless the state is NORMAL.
78
+ """
79
+ def __init__(self, container):
80
+ self.container = container
81
+ ttk.Frame.__init__(self, container)
82
+ self.scrollbar = AutoScrollbar(self, orient=Tk_.VERTICAL)
83
+ self.text = text = Tk_.Text(self, width=60, height=12,
84
+ highlightthickness=0, relief=Tk_.FLAT,
85
+ yscrollcommand=self.scrollbar.set)
86
+ self.scrollbar.config(command=text.yview)
87
+ self.grid_columnconfigure(0, weight=1)
88
+ text.grid(row=0, column=0, sticky=Tk_.NSEW)
89
+ text.bind('<<Copy>>', self.copy)
90
+ text.bind('<Button-1>', lambda *args: self.text.focus_set())
91
+ text.bind('<FocusOut>', self.focus_out)
92
+ self.scrollbar.grid(row=0, column=1, sticky=Tk_.NS)
93
+ self.text.config(state=Tk_.DISABLED)
94
+
95
+ def focus_out(self, *args):
96
+ self.text.config(state=Tk_.NORMAL)
97
+ self.text.selection_clear()
98
+ self.text.config(state=Tk_.DISABLED)
99
+
100
+ def set(self, message):
101
+ self.text.config(state=Tk_.NORMAL)
102
+ self.text.delete('0.1', Tk_.END)
103
+ self.text.selection_clear()
104
+ self.text.insert(Tk_.INSERT, message)
105
+ self.text.config(state=Tk_.DISABLED)
106
+
107
+ def get(self):
108
+ return self.text.get('0.1', Tk_.END)
109
+
110
+ def copy(self, event):
111
+ self.text.selection_get(selection='CLIPBOARD')
112
+
113
+
114
+ class DirichletTab(PolyhedronViewer):
115
+ def __init__(self, container, facedicts=[], title='Polyhedron Tab', parent=None):
116
+ self.main_window = main_window
117
+ self.style = style = SnapPyStyle()
118
+ PolyhedronViewer.__init__(self, container, facedicts=facedicts,
119
+ title=title, bgcolor=style.groupBG)
120
+
121
+ def update_menus(self, menubar):
122
+ menubar.children['help'].activate(
123
+ [ app_menus.help_polyhedron_viewer_label,
124
+ app_menus.help_report_bugs_label ])
125
+
126
+
127
+ class CuspNeighborhoodTab(HoroballViewer):
128
+ def __init__(self, nbhd, title='Polyhedron Tab'):
129
+ self.main_window = main_window
130
+ style = SnapPyStyle()
131
+ if main_window:
132
+ HoroballViewer.__init__(self, nbhd, title=title,
133
+ bgcolor=style.groupBG, settings=main_window.settings)
134
+ else:
135
+ HoroballViewer.__init__(self, nbhd, title=title,
136
+ bgcolor=style.groupBG)
137
+
138
+ def update_menus(self, menubar):
139
+ menubar.children['help'].activate(
140
+ [ app_menus.help_horoball_viewer_label,
141
+ app_menus.help_report_bugs_label])
142
+
143
+
144
+ class LinkTab(LinkViewer):
145
+ def __init__(self, data, window):
146
+ self.style = style = SnapPyStyle()
147
+ self.canvas = canvas = Tk_.Canvas(window, bg=style.groupBG,
148
+ highlightthickness=0, highlightcolor=style.groupBG)
149
+ LinkViewer.__init__(self, canvas, data)
150
+ canvas.bind("<Configure>", lambda event : self.draw())
151
+
152
+ def close(self, event=None):
153
+ pass
154
+
155
+
156
+ class Browser(Tk_.Toplevel):
157
+ """
158
+ Toplevel window displaying a Dehn filling control panel and
159
+ a notebook with tabs that show numerical or graphical information
160
+ about the manifold.
161
+ """
162
+ def __init__(self, manifold, root=None, main_window=None):
163
+ if root is None:
164
+ if Tk_._default_root:
165
+ self.root = root = Tk_._default_root
166
+ else:
167
+ self.root = root = IPythonTkRoot(window_type='Browser')
168
+ root.withdraw()
169
+ else:
170
+ self.root = root
171
+ Tk_.Toplevel.__init__(self, root, class_='snappy')
172
+ self.update_idletasks()
173
+ if isinstance(root, IPythonTkRoot):
174
+ self.withdraw()
175
+ # Avoid showing an empty root window on the screen.
176
+ self.root.after(100, self.deiconify)
177
+ if manifold.num_tetrahedra() == 0:
178
+ raise ValueError('The empty Manifold cannot be browsed.')
179
+ self.manifold = manifold
180
+ self.aka_after_id = None
181
+ self.main_window = main_window
182
+ self.symmetry_group = None
183
+ self.dirichlet = []
184
+ self.cusp_nbhd = None
185
+ self.length_spectrum = []
186
+ self.recompute_invariants = True
187
+ self.style = style = SnapPyStyle()
188
+ self.title(manifold.name())
189
+ self.config(bg=style.groupBG)
190
+ self.protocol("WM_DELETE_WINDOW", self.close)
191
+ if sys.platform == 'darwin':
192
+ self.bind_all('<Command-Key-w>', self.close)
193
+ elif sys.platform == 'linux':
194
+ self.bind_all('<Alt-Key-F4>', self.close)
195
+ self.side_panel = side_panel = self.build_side_panel()
196
+
197
+ self.notebook = notebook = ttk.Notebook(self)
198
+ self.invariants_tab = invariants_tab = self.build_invariants()
199
+ self.dirichlet_viewer = DirichletTab(self)
200
+ self.horoball_viewer = CuspNeighborhoodTab(self)
201
+ self.fillings_changed_callback = None
202
+
203
+ self.bottombar = bottombar = ttk.Frame(self, height=20)
204
+ bg = self.style.ttk_style.lookup('TLable', 'background')
205
+ fg = self.style.ttk_style.lookup('TLable', 'foreground')
206
+ self.modeline = modeline = Tk_.Text(
207
+ self.bottombar, height=1,
208
+ relief=Tk_.FLAT,
209
+ background=bg,
210
+ foreground=fg,
211
+ selectborderwidth=0,
212
+ highlightbackground=bg,
213
+ highlightcolor=bg,
214
+ highlightthickness=0,
215
+ takefocus=False,
216
+ state=Tk_.DISABLED)
217
+ self.modeline.tag_config('alert', foreground='red')
218
+
219
+ self.inside_view = None
220
+
221
+ self.symmetry_tab = symmetry_tab = self.build_symmetry()
222
+ self.link_tab = link_tab = self.build_link()
223
+ notebook.add(invariants_tab, text='Invariants', padding=[0])
224
+ notebook.add(self.dirichlet_viewer, text='Dirichlet')
225
+ notebook.add(self.horoball_viewer, text='Cusp Nbhds')
226
+ notebook.add(self.build_inside_view(), text='Inside View')
227
+ notebook.add(symmetry_tab, text='Symmetry', padding=[0])
228
+ if link_tab:
229
+ notebook.add(link_tab.canvas, text='Link')
230
+ notebook.bind('<<NotebookTabChanged>>', self.update_current_tab)
231
+
232
+ self.build_menus()
233
+ self.config(menu=self.menubar)
234
+ self.grid_columnconfigure(1, weight=1)
235
+ self.grid_rowconfigure(0, weight=1)
236
+ side_panel.grid(row=0, column=0, sticky=Tk_.NSEW, padx=0, pady=0)
237
+ notebook.grid(row=0, column=1, sticky=Tk_.NSEW, padx=0, pady=0, ipady=5)
238
+ bottombar.grid(row=1, columnspan=2, sticky=Tk_.NSEW)
239
+ self.modeline.pack(fill=Tk_.BOTH, expand=True, padx=30)
240
+ self.update_modeline()
241
+ self.update_idletasks()
242
+ self.wm_geometry(self.wm_geometry())
243
+ # Make sure the invariants get computed, even on Windows.
244
+ self.after_idle(self.update_current_tab)
245
+
246
+ def __repr__(self):
247
+ return 'Browser window for %s\n' % self.manifold
248
+
249
+ build_menus = browser_menus
250
+
251
+ def build_side_panel(self):
252
+ side_panel = ttk.Frame(self)
253
+ side_panel.grid_rowconfigure(5, weight=1)
254
+ filling = ttk.Labelframe(side_panel, text='Filling Curves',
255
+ padding=(10, 10))
256
+ self.filling_canvas = None
257
+ num_cusps = self.manifold.num_cusps()
258
+ if num_cusps > 3:
259
+ filling.grid_propagate(False)
260
+ filling.configure(width=cusp_box_width + 20,
261
+ height=int(3.5*cusp_box_height))
262
+ filling.grid_columnconfigure(0, weight=1)
263
+ filling.grid_rowconfigure(0, weight=1)
264
+ filling_scrollbar = ttk.Scrollbar(filling)
265
+ filling_scrollbar.grid(row=0, column=1, sticky=Tk_.NS)
266
+ self.filling_canvas = canvas = Tk_.Canvas(filling, bd=0,
267
+ highlightthickness=0,
268
+ yscrollcommand=filling_scrollbar.set,
269
+ scrollregion=(0, 0, cusp_box_width + 20,
270
+ cusp_box_height*num_cusps + 10)
271
+ )
272
+ if sys.platform == 'darwin':
273
+ canvas.configure(background=self.style.groupBG)
274
+ canvas.grid(row=0, column=0, sticky=Tk_.NSEW)
275
+ filling_scrollbar.config(command=canvas.yview)
276
+ self.filling_vars = []
277
+
278
+ # Embedded windows in a canvas are clipped to their parent, not to
279
+ # the canvas.
280
+ cusp_parent = self.filling_canvas if self.filling_canvas else filling
281
+ for n in range(num_cusps):
282
+ R, G, B, A = GetColor(n)
283
+ color = '#%.3x%.3x%.3x' % (int(R*4095), int(G*4095), int(B*4095))
284
+ cusp = ttk.Labelframe(cusp_parent, text='Cusp %d' % n)
285
+ mer_var = Tk_.StringVar(self, value='0')
286
+ long_var = Tk_.StringVar(self, value='0')
287
+ self.filling_vars.append((mer_var, long_var))
288
+ Tk_.Label(cusp, width=0, background=color, bd=1,).grid(
289
+ row=0, column=0, rowspan=2, sticky=Tk_.NS, padx=4, pady=8)
290
+ ttk.Label(cusp, text='Meridian:').grid(
291
+ row=0, column=1, sticky=Tk_.E)
292
+ ttk.Label(cusp, text='Longitude:').grid(
293
+ row=1, column=1, sticky=Tk_.E)
294
+ meridian = Spinbox(cusp, width=4, textvariable=mer_var,
295
+ from_=-1000, to=1000, increment=1,
296
+ name=':%s:0' % n, validate='focusout',
297
+ validatecommand=(self.register(self.validate_coeff),'%P','%W')
298
+ )
299
+ meridian.bind('<Return>', self.do_filling)
300
+ meridian.grid(row=0, column=2, sticky=Tk_.W, padx=0, pady=3)
301
+ longitude = Spinbox(cusp, width=4, textvariable=long_var,
302
+ from_=-1000, to=1000, increment=1,
303
+ name=':%s:1' % n, validate='focusout',
304
+ validatecommand=(self.register(self.validate_coeff),'%P','%W')
305
+ )
306
+ longitude.bind('<Return>', self.do_filling)
307
+ longitude.grid(row=1, column=2, sticky=Tk_.W, padx=0, pady=3)
308
+ if self.filling_canvas:
309
+ self.filling_canvas.create_window(0, n*cusp_box_height,
310
+ anchor=Tk_.NW, window=cusp)
311
+ else:
312
+ cusp.grid(row=n, pady=8)
313
+ filling.grid(row=0, column=0, padx=10, pady=10)
314
+ modify = ttk.Labelframe(side_panel, text='Modify', padding=(10, 10))
315
+ self.fill_button = ttk.Button(modify, text='Fill', command=self.do_filling
316
+ ).pack(padx=10, pady=5, expand=True, fill=Tk_.X)
317
+ ttk.Button(modify, text='Retriangulate', command=self.retriangulate
318
+ ).pack(padx=10, pady=5, expand=True, fill=Tk_.X)
319
+ modify.grid(row=1, column=0, padx=10, pady=10, sticky=Tk_.EW)
320
+ create = ttk.Labelframe(side_panel, text='Create', padding=(10, 10))
321
+ ttk.Button(create, text='Drill ...', command=self.drill
322
+ ).pack(padx=10, pady=5, expand=True, fill=Tk_.X)
323
+ ttk.Button(create, text='Cover ...', command=self.cover
324
+ ).pack(padx=10, pady=5, expand=True, fill=Tk_.X)
325
+ create.grid(row=2, column=0, padx=10, pady=10, sticky=Tk_.EW)
326
+ return side_panel
327
+
328
+ def build_invariants(self):
329
+ style = self.style
330
+ frame = ttk.Frame(self)
331
+ frame.grid_columnconfigure(1, weight=1)
332
+ self.basic = basic = ttk.LabelFrame(frame, text="Basic Invariants",
333
+ padding=(10, 10))
334
+ for n in range(4):
335
+ basic.grid_rowconfigure(n, weight=1)
336
+ self.volume = SelectableText(basic, labeltext='Volume:')
337
+ self.volume.grid(row=0, column=0, padx=5, pady=0, sticky=Tk_.E)
338
+ self.cs = SelectableText(basic, labeltext='Chern-Simons:')
339
+ self.cs.grid(row=1, column=0, padx=5, pady=0, sticky=Tk_.E)
340
+ self.homology = SelectableText(basic, labeltext='H\u2081:')
341
+ self.homology.grid(row=2, column=0, padx=5, pady=0, sticky=Tk_.E)
342
+ self.orientability = SelectableText(basic, labeltext='Orientable:')
343
+ self.orientability.grid(row=3, column=0, padx=5, pady=0, sticky=Tk_.E)
344
+ basic.grid(row=0, column=0, sticky=Tk_.NSEW, padx=10, pady=10)
345
+
346
+ self.aka = ttk.LabelFrame(frame, text='Also Known As', padding=(10, 10))
347
+ self.aka_viewer = aka_viewer = ttk.Treeview(
348
+ self.aka,
349
+ selectmode='none',
350
+ height=2 if sys.platform == 'linux' else 4,
351
+ columns=['manifold', 'as_link'],
352
+ show='headings')
353
+ aka_viewer.heading('manifold', text='Manifold')
354
+ aka_viewer.column('manifold', stretch=True, width=100)
355
+ aka_viewer.heading('as_link', text='Same Link')
356
+ aka_viewer.column('as_link', stretch=True, width=100)
357
+ aka_viewer.pack(expand=True, fill=Tk_.BOTH)
358
+ self.aka.grid(row=1, column=0, padx=10, pady=10, sticky=Tk_.NSEW)
359
+
360
+ self.fundamental = fundamental = ttk.LabelFrame(frame,
361
+ text="Fundamental Group", padding=(10, 10))
362
+ self.pi_one = SelectableMessage(fundamental)
363
+ self.pi_one.grid(row=0, column=0, padx=5, pady=5, sticky=Tk_.W)
364
+ self.pi_one_options = ttk.Frame(fundamental)
365
+ self.simplify_var = Tk_.BooleanVar(fundamental, value=True)
366
+ self.simplify = ttk.Checkbutton(self.pi_one_options,
367
+ variable=self.simplify_var,
368
+ text='simplified presentation',
369
+ command=self.compute_pi_one)
370
+ self.simplify.grid(row=0, column=0, sticky=Tk_.W)
371
+ self.minimize_var = Tk_.BooleanVar(fundamental, value=True)
372
+ self.minimize = ttk.Checkbutton(self.pi_one_options,
373
+ variable=self.minimize_var,
374
+ text='minimal number of generators',
375
+ command=self.compute_pi_one)
376
+ self.minimize.grid(row=1, column=0, sticky=Tk_.W)
377
+ self.gens_change_var = Tk_.BooleanVar(fundamental, value=True)
378
+ self.gens_change = ttk.Checkbutton(self.pi_one_options,
379
+ variable=self.gens_change_var,
380
+ text='fillings may affect generators',
381
+ command=self.compute_pi_one)
382
+ self.gens_change.grid(row=2, column=0, sticky=Tk_.W)
383
+ self.pi_one_options.grid(row=1, column=0,
384
+ padx=10, pady=10, sticky=Tk_.W)
385
+ fundamental.grid(row=0, column=1, rowspan=2, padx=10, pady=10,
386
+ sticky=Tk_.W)
387
+
388
+ self.length_spectrum_frame = ttk.LabelFrame(frame,
389
+ text='Length Spectrum', padding=(10, 10))
390
+ self.length_spectrum_frame.grid_columnconfigure(1, weight=1)
391
+ ttk.Label(self.length_spectrum_frame, text='Cutoff:').grid(
392
+ row=0, column=0, sticky=Tk_.E, pady=5)
393
+ self.length_cutoff = 1.0
394
+ self.cutoff_var = Tk_.StringVar(self, self.length_cutoff)
395
+ self.cutoff_entry = cutoff_entry = ttk.Entry(
396
+ self.length_spectrum_frame,
397
+ takefocus=False,
398
+ width=6,
399
+ textvariable=self.cutoff_var,
400
+ validate='focusout',
401
+ validatecommand=(self.register(self.validate_cutoff),'%P')
402
+ )
403
+ cutoff_entry.bind('<Return>', lambda event : self.focus_set())
404
+ cutoff_entry.grid(row=0, column=1, sticky=Tk_.W, pady=5)
405
+ self.geodesics = geodesics = ttk.Treeview(self.length_spectrum_frame,
406
+ height=6, show='headings', selectmode='none',
407
+ columns=['mult', 'length', 'topology', 'parity'],
408
+ )
409
+ # TODO: compute column widths by measuring text.
410
+ geodesics.heading('mult', text='Mult.')
411
+ geodesics.column('mult', stretch=False, width=60)
412
+ geodesics.heading('length', text='Complex Length')
413
+ geodesics.column('length', stretch=True, minwidth=360)
414
+ geodesics.heading('topology', text='Topology')
415
+ geodesics.column('topology', stretch=True, width=100)
416
+ geodesics.heading('parity', text='Parity')
417
+ geodesics.column('parity', stretch=True, width=80)
418
+ geodesics.grid(row=1, column=0, columnspan=2, sticky=Tk_.EW, padx=10,
419
+ pady=10)
420
+ self.length_spectrum_frame.grid(row=4, columnspan=2, padx=10, pady=10,
421
+ sticky=Tk_.NSEW)
422
+ return frame
423
+
424
+ def build_symmetry(self):
425
+ style = self.style
426
+ frame = ttk.Frame(self)
427
+ frame.grid_columnconfigure(0, weight=1)
428
+ self.symmetry = SelectableText(frame, labeltext='Symmetry Group:',
429
+ width=30, depth=1)
430
+ self.symmetry.grid(row=0, column=0, pady=20)
431
+ message1 = ttk.Label(frame,
432
+ text='Future releases of SnapPy will show more information here.')
433
+ message2 = ttk.Label(frame,
434
+ text='Type SymmetryGroup.<tab> in the command shell to see '
435
+ 'what is available.')
436
+ message1.grid(row=1, column=0, pady=(40, 10))
437
+ message2.grid(row=2, column=0)
438
+ return frame
439
+
440
+ def build_link(self):
441
+ if self.manifold.DT_code() is not None:
442
+ data = None
443
+ try:
444
+ data = OrthogonalLinkDiagram(self.manifold.link()).plink_data()
445
+ except:
446
+ if self.manifold.LE:
447
+ data = self.manifold.LE.pickle()
448
+ if data:
449
+ return LinkTab(data, self)
450
+
451
+ def build_inside_view(self):
452
+ if not self.manifold.is_orientable():
453
+ text = ("Inside view for non-orientable manifolds such as %s "
454
+ "is not supported yet.") % self.manifold.name()
455
+ return ttk.Label(self, text=text)
456
+
457
+ try:
458
+ # delayed import to avoid cycle
459
+ from .raytracing.inside_viewer import InsideViewer
460
+ self.inside_view = InsideViewer(self, self.manifold,
461
+ fillings_changed_callback=self.update_modeline_and_side_panel)
462
+ self.fillings_changed_callback = self.inside_view.pull_fillings_from_manifold
463
+ return self.inside_view
464
+ except Exception:
465
+ import traceback
466
+ text = ("Could not instantiate inside view. "
467
+ "Error was:\n\n%s" % traceback.format_exc())
468
+ return ttk.Label(self, text=text)
469
+
470
+ def update_menus(self, menubar):
471
+ """Default menus used by the Invariants, Symmetry and Link tabs."""
472
+ menubar.children['help'].activate([])
473
+
474
+ def update_modeline(self):
475
+ modeline = self.modeline
476
+ modeline.config(state=Tk_.NORMAL)
477
+ modeline.delete(1.0, Tk_.END)
478
+ if not self.manifold.is_orientable():
479
+ modeline.insert(Tk_.END, 'Non-orientable; ')
480
+ modeline.insert(Tk_.END, '%s tetrahedra; %s' % (
481
+ self.manifold.num_tetrahedra(), self.manifold.solution_type()))
482
+ if len(self.dirichlet) == 0:
483
+ modeline.insert(Tk_.END,
484
+ ' * failed to compute Dirichlet domain!',
485
+ 'alert')
486
+ modeline.config(state=Tk_.DISABLED)
487
+
488
+ def update_modeline_and_side_panel(self):
489
+ self.update_modeline()
490
+ self.update_side_panel()
491
+
492
+ def update_current_tab(self, event=None):
493
+ self.update_modeline_and_side_panel()
494
+ tab_name = self.notebook.tab(self.notebook.select(), 'text')
495
+ if tab_name == 'Invariants':
496
+ self.update_menus(self.menubar)
497
+ self.update_invariants()
498
+ elif tab_name == 'Cusp Nbhds':
499
+ self.horoball_viewer.update_menus(self.menubar)
500
+ self.horoball_viewer.view_menu.focus_set()
501
+ if self.horoball_viewer.empty:
502
+ self.update_cusps()
503
+ else:
504
+ self.horoball_viewer.redraw()
505
+ elif tab_name == 'Dirichlet':
506
+ self.dirichlet_viewer.update_menus(self.menubar)
507
+ elif tab_name == 'Link':
508
+ self.update_menus(self.menubar)
509
+ self.link_tab.draw()
510
+ elif tab_name == 'Inside View':
511
+ self.inside_view.widget.focus_set()
512
+ elif tab_name == 'Symmetry':
513
+ self.update_menus(self.menubar)
514
+ self.update_symmetry()
515
+ else:
516
+ self.update_menus(self.menubar)
517
+ self.update_idletasks()
518
+
519
+ def update_side_panel(self):
520
+ current_fillings = [c.filling for c in self.manifold.cusp_info()]
521
+ for n, coeffs in enumerate(current_fillings):
522
+ for m in (0,1):
523
+ value = '%g' % coeffs[m]
524
+ value = '0' if value == '-0' else value
525
+ self.filling_vars[n][m].set(value)
526
+
527
+ def update_invariants(self):
528
+ manifold = self.manifold
529
+ if not self.recompute_invariants:
530
+ return
531
+ self.orientability.set('Yes' if manifold.is_orientable() else 'No')
532
+ try:
533
+ self.volume.set(repr(manifold.volume()))
534
+ except ValueError:
535
+ self.volume.set('')
536
+ try:
537
+ self.cs.set(repr(manifold.chern_simons()))
538
+ except ValueError:
539
+ self.cs.set('')
540
+ try:
541
+ self.homology.set(repr(manifold.homology()))
542
+ except ValueError:
543
+ self.homology.set('')
544
+ self.compute_pi_one()
545
+ self.update_dirichlet()
546
+ self.update_length_spectrum()
547
+ self.update_aka()
548
+ self.recompute_invariants = False
549
+
550
+ def clear_invariants(self):
551
+ self.volume.set('')
552
+ self.cs.set('')
553
+ self.homology.set('')
554
+ self.pi_one.set('')
555
+ self.geodesics.delete(*self.geodesics.get_children())
556
+ self.symmetry.set('')
557
+ self.recompute_invariants = True
558
+
559
+ def update_length_spectrum(self):
560
+ OK = True
561
+ try:
562
+ self.length_spectrum = self.manifold.length_spectrum(
563
+ self.length_cutoff)
564
+ except RuntimeError:
565
+ OK = False
566
+ self.length_spectrum = []
567
+ self.geodesics.delete(*self.geodesics.get_children())
568
+ self.cutoff_entry.selection_clear()
569
+ if OK:
570
+ for geodesic in self.length_spectrum:
571
+ parity = '+' if geodesic['parity'].endswith('preserving') else '-'
572
+ self.geodesics.insert('', 'end', values=(
573
+ geodesic['multiplicity'],
574
+ Number(geodesic['length'], accuracy=25),
575
+ geodesic['topology'],
576
+ parity))
577
+ else:
578
+ self.geodesics.insert('', 'end', values=(
579
+ '?', 'Not computable without a Dirichlet domain', '?', '?'))
580
+
581
+ def update_aka(self):
582
+ self._write_aka_info()
583
+ # self.identifier.identify(self.manifold)
584
+ # self.aka_after_id = self.after(100, self._aka_callback)
585
+ M = self.manifold.copy()
586
+
587
+ def format_name(N):
588
+ if all(N.cusp_info('is_complete')):
589
+ return N.name()
590
+ return repr(N)
591
+ try:
592
+ mflds = {
593
+ 'weak' : [format_name(N) for N in M.identify()],
594
+ 'strong' : [format_name(N) for N in M.identify(True)] }
595
+ except ValueError:
596
+ mflds = {
597
+ 'weak' : [],
598
+ 'strong' : [] }
599
+ self._write_aka_info(mflds)
600
+
601
+ def _aka_callback(self):
602
+ # Not used, since the Identifier does not work in a Mac GUI
603
+ self.after_cancel(self.aka_after_id)
604
+ self.aka_after_id = None
605
+ if self.identifier.state == 'finished':
606
+ self._write_aka_info(self.identifier.get())
607
+ else:
608
+ self.aka_after_id = self.after(1000, self._aka_callback)
609
+
610
+ def _write_aka_info(self, mflds=None):
611
+ aka_viewer = self.aka_viewer
612
+ try:
613
+ all_items = aka_viewer.get_children()
614
+ except Tk_.TclError: # the widget has been destroyed
615
+ return
616
+ if all_items:
617
+ aka_viewer.delete(*all_items)
618
+ if mflds is None:
619
+ aka_viewer.insert('', 'end', values=('Working ...', ''))
620
+ else:
621
+ strong = set(mflds['strong'])
622
+ weak = set(mflds['weak']) - strong
623
+ for mfld in strong:
624
+ aka_viewer.insert('', 'end', values=(mfld,'Yes'))
625
+ for mfld in weak:
626
+ aka_viewer.insert('', 'end', values=(mfld,'No'))
627
+
628
+ def update_dirichlet(self):
629
+ try:
630
+ self.dirichlet = self.manifold.dirichlet_domain().face_list()
631
+ except RuntimeError:
632
+ self.dirichlet = []
633
+ self.update_modeline()
634
+ self.dirichlet_viewer.new_polyhedron(self.dirichlet)
635
+ if self.inside_view:
636
+ self.inside_view.show_failed_dirichlet(
637
+ show=len(self.dirichlet) == 0)
638
+
639
+ def update_cusps(self):
640
+ try:
641
+ self.cusp_nbhd = self.manifold.cusp_neighborhood()
642
+ except RuntimeError:
643
+ self.cusp_nbhd = None
644
+ self.horoball_viewer.new_scene(self.cusp_nbhd)
645
+ self.after(100,
646
+ self.horoball_viewer.cutoff_entry.selection_clear)
647
+
648
+ def update_symmetry(self):
649
+ 'update_symmetry'
650
+ try:
651
+ self.symmetry_group = self.manifold.symmetry_group()
652
+ except (ValueError, SnapPeaFatalError):
653
+ self.symmetry_group = str('unknown')
654
+ self.symmetry.set(str(self.symmetry_group))
655
+
656
+ def validate_coeff(self, P, W):
657
+ tkname, cusp, curve = W.split(':')
658
+ cusp, curve = int(cusp), int(curve)
659
+ try:
660
+ float(P)
661
+ except ValueError:
662
+ var = self.filling_vars[cusp][curve]
663
+ if P == '':
664
+ var.set('0')
665
+ else:
666
+ value = '%g' % self.manifold.cusp_info()[cusp].filling[curve]
667
+ value = '0' if value == '-0' else value
668
+ var.set(value)
669
+ return False
670
+ return True
671
+
672
+ def validate_cutoff(self, P):
673
+ try:
674
+ cutoff = float(P)
675
+ if self.length_cutoff != cutoff:
676
+ self.length_cutoff = cutoff
677
+ self.update_length_spectrum()
678
+ except ValueError:
679
+ self.after_idle(
680
+ self.cutoff_var.set, str(self.length_cutoff))
681
+ return False
682
+ return True
683
+
684
+ def do_filling(self, event=None):
685
+ filling_spec = [( float(x[0].get() if x[0].get() else 0),
686
+ float(x[1].get() if x[1].get() else 0) )
687
+ for x in self.filling_vars]
688
+ self.config(cursor='watch')
689
+ self.clear_invariants()
690
+ self.manifold.dehn_fill(filling_spec)
691
+ current_fillings = [c.filling for c in self.manifold.cusp_info()]
692
+ for n, coeffs in enumerate(current_fillings):
693
+ for m in (0, 1):
694
+ value = '%g' % coeffs[m]
695
+ value = '0' if value == '-0' else value
696
+ self.filling_vars[n][m].set(value)
697
+ self.update_cusps()
698
+ self.update_current_tab()
699
+ self.config(cursor='')
700
+
701
+ if self.fillings_changed_callback:
702
+ self.fillings_changed_callback()
703
+
704
+ def drill(self):
705
+ dialog = Driller(self, self.manifold)
706
+ dialog.go()
707
+ for n in dialog.result:
708
+ self.manifold.drill(n).browse()
709
+
710
+ def cover(self):
711
+ dialog = Coverer(self, self.manifold)
712
+ dialog.go()
713
+ for manifold in dialog.result:
714
+ manifold.browse()
715
+
716
+ def retriangulate(self):
717
+ self.manifold.randomize()
718
+ self.clear_invariants()
719
+ self.update_current_tab()
720
+
721
+ def compute_pi_one(self):
722
+ fun_gp = self.manifold.fundamental_group(
723
+ simplify_presentation=self.simplify_var.get(),
724
+ minimize_number_of_generators=self.minimize_var.get(),
725
+ fillings_may_affect_generators=self.gens_change_var.get())
726
+ self.pi_one.set(repr(fun_gp))
727
+
728
+ def save(self, event=None):
729
+ self.manifold.save()
730
+
731
+ def close(self, event=None):
732
+ self.destroy()
733
+
734
+ def edit_actions(self):
735
+ tab_name = self.notebook.tab(self.notebook.select(), 'text')
736
+ if tab_name in ('Invariants', 'Link', 'Symmetry'):
737
+ try:
738
+ selected = self.selection_get()
739
+ except:
740
+ selected = False
741
+ if selected:
742
+ return {'Copy': self.edit_copy}
743
+ return {}
744
+
745
+ def edit_copy(self):
746
+ try:
747
+ self.clipboard_clear()
748
+ self.clipboard_append(self.selection_get())
749
+ self.selection_clear()
750
+ except:
751
+ pass
752
+
753
+ def dirichlet_help(self):
754
+ self.dirichlet_viewer.widget.help()
755
+
756
+ def horoball_help(self):
757
+ self.horoball_viewer.widget.help()
758
+
759
+ def test(self, use_modernopengl=True):
760
+ self.update_idletasks()
761
+ print('Testing browser')
762
+ self.after(1000, self.notebook.select, self.dirichlet_viewer)
763
+ self.after(2500, self.notebook.select, self.horoball_viewer)
764
+ if use_modernopengl:
765
+ self.after(4000, self.notebook.select, self.inside_view)
766
+ if self.link_tab:
767
+ self.after(5500, self.notebook.select, self.link_tab.canvas)
768
+ self.after(7000, self.close)
769
+ else:
770
+ self.after(5500, self.close)
771
+ self.wait_window(self)
772
+
773
+
774
+ class Driller(SimpleDialog):
775
+ def __init__(self, parent, manifold):
776
+ self.manifold = manifold
777
+ self.num = 0 # make the superclass happy
778
+ self.max_segments = 6
779
+ self.result = []
780
+ style = SnapPyStyle()
781
+ self.root = root = Tk_.Toplevel(parent, class_='SnapPy', bg=style.windowBG)
782
+ title = 'Drill'
783
+ root.title(title)
784
+ root.iconname(title)
785
+ root.bind('<Return>', self.handle_return)
786
+ top_frame = ttk.Frame(self.root)
787
+ top_frame.grid_columnconfigure(0, weight=1)
788
+ top_frame.grid_rowconfigure(2, weight=1)
789
+ msg_font = dict(family=style.font_info['family'],
790
+ weight='bold',
791
+ size=int(style.font_info['size']*1.2))
792
+ msg = ttk.Label(top_frame, font=msg_font,
793
+ text='Choose which curves to drill out:')
794
+ msg.grid(row=0, column=0, pady=10)
795
+ segment_frame = ttk.Frame(top_frame)
796
+ self.segment_var = segment_var = Tk_.StringVar(root)
797
+ segment_var.set(str(self.max_segments))
798
+ ttk.Label(segment_frame, text='Max segments: ').pack(
799
+ side=Tk_.LEFT, padx=4)
800
+ self.segment_entry = segment_entry = ttk.Entry(
801
+ segment_frame,
802
+ takefocus=False,
803
+ width=2,
804
+ textvariable=segment_var,
805
+ validate='focusout',
806
+ validatecommand=(root.register(self.validate_segments),'%P')
807
+ )
808
+ segment_entry.pack(side=Tk_.LEFT)
809
+ segment_frame.grid(row=1, column=0, pady=2)
810
+ self.curves = curves = ttk.Treeview(
811
+ top_frame,
812
+ selectmode='extended',
813
+ columns=['index', 'parity', 'length'],
814
+ show='headings')
815
+ curves.heading('index', text='#')
816
+ curves.column('index', stretch=False, width=20)
817
+ curves.heading('parity', text='Parity')
818
+ curves.column('parity', stretch=False, width=80)
819
+ curves.heading('length', text='Length')
820
+ curves.column('length', stretch=True, width=460)
821
+ curves.bind('<Double-Button-1>', self.drill)
822
+ self.curves.grid(row=2, column=0, padx=6, pady=6, sticky=Tk_.NSEW)
823
+ self.show_curves()
824
+ top_frame.pack(fill=Tk_.BOTH, expand=1)
825
+ button_frame = ttk.Frame(self.root)
826
+ button = ttk.Button(button_frame, text='Drill', command=self.drill,
827
+ default='active')
828
+ button.pack(side=Tk_.LEFT, padx=6)
829
+ button = ttk.Button(button_frame, text='Cancel', command=self.cancel)
830
+ button.pack(side=Tk_.LEFT, padx=6)
831
+ button_frame.pack(pady=6)
832
+ self.root.protocol('WM_DELETE_WINDOW', self.wm_delete_window)
833
+ _place_window(self.root, parent)
834
+
835
+ def show_curves(self):
836
+ self.curves.delete(*self.curves.get_children())
837
+ for curve in self.manifold.dual_curves(max_segments=self.max_segments):
838
+ n = curve['index']
839
+ parity = '+' if curve['parity'] == 1 else '-'
840
+ length = Number(curve['filled_length'], precision=25)
841
+ self.curves.insert( '', 'end', values=(n, parity, length) )
842
+
843
+ def handle_return(self, event):
844
+ if event.widget != self.segment_entry:
845
+ self.drill()
846
+ else:
847
+ self.curves.focus_set()
848
+
849
+ def drill(self, event=None):
850
+ self.result = [self.curves.index(x) for x in self.curves.selection()]
851
+ self.root.quit()
852
+
853
+ def cancel(self):
854
+ self.root.quit()
855
+
856
+ def validate_segments(self, P):
857
+ try:
858
+ new_max = int(P)
859
+ if self.max_segments != new_max:
860
+ self.max_segments = new_max
861
+ self.segment_var.set(str(self.max_segments))
862
+ self.show_curves()
863
+ except ValueError:
864
+ self.root.after_idle(
865
+ self.segment_var.set, str(self.max_segments))
866
+ return False
867
+ return True
868
+
869
+
870
+ class Coverer(SimpleDialog):
871
+ def __init__(self, parent, manifold):
872
+ self.manifold = manifold.copy()
873
+ self.num = 0 # make the superclass happy
874
+ self.result = []
875
+ style = SnapPyStyle()
876
+ self.root = root = Tk_.Toplevel(parent, class_='SnapPy', bg=style.windowBG)
877
+ title = 'Cover'
878
+ root.title(title)
879
+ root.iconname(title)
880
+ root.bind('<Return>', self.handle_return)
881
+ top_frame = ttk.Frame(root)
882
+ top_frame.grid_rowconfigure(2, weight=1)
883
+ top_frame.grid_columnconfigure(0, weight=1)
884
+ top_frame.grid_columnconfigure(1, weight=1)
885
+ msg_font = dict(family=style.font_info['family'],
886
+ weight='bold',
887
+ size=int(style.font_info['size']*1.2))
888
+ msg = ttk.Label(top_frame, font=msg_font,
889
+ text='Choose covering spaces to browse:')
890
+ msg.grid(row=0, column=0, columnspan=3, pady=10)
891
+ degree_frame = ttk.Frame(top_frame)
892
+ degree_frame.grid_columnconfigure(2, weight=1)
893
+ self.degree_var = degree_var = Tk_.StringVar()
894
+ ttk.Label(degree_frame, text='Degree: ').grid(
895
+ row=0, column=0, sticky=Tk_.E)
896
+ self.degree_option = degree_option = ttk.OptionMenu(
897
+ degree_frame,
898
+ degree_var,
899
+ None,
900
+ *range(2,9)
901
+ )
902
+ degree_option.grid(row=0, column=1)
903
+ self.cyclic_var = cyclic_var = Tk_.BooleanVar()
904
+ cyclic_or_not = ttk.Checkbutton(degree_frame,
905
+ variable=cyclic_var,
906
+ text='cyclic covers only',
907
+ )
908
+ cyclic_or_not.grid(row=0, column=2, padx=6, sticky=Tk_.W)
909
+ degree_frame.grid(row=1, column=0, pady=2, padx=6, sticky=Tk_.EW)
910
+ self.covers = covers = ttk.Treeview(
911
+ top_frame,
912
+ selectmode='extended',
913
+ columns=['index', 'cover_type', 'num_cusps', 'homology'],
914
+ show='headings')
915
+ covers.heading('index', text='')
916
+ covers.column('index', stretch=False, width=40, minwidth=40)
917
+ covers.heading('cover_type', text='Type')
918
+ covers.column('cover_type', stretch=False, width=100)
919
+ covers.heading('num_cusps', text='# Cusps')
920
+ covers.column('num_cusps', stretch=False, width=100, anchor=Tk_.CENTER)
921
+ covers.heading('homology', text='Homology')
922
+ covers.column('homology', stretch=True, width=300)
923
+ covers.bind('<Double-Button-1>', self.choose)
924
+ self.covers.grid(row=2, column=0, columnspan=2, padx=6, pady=6,
925
+ sticky=Tk_.NSEW)
926
+ top_frame.pack(fill=Tk_.BOTH, expand=1)
927
+ button_frame = ttk.Frame(self.root)
928
+ button_frame.grid_columnconfigure(0, weight=1)
929
+ button_frame.grid_columnconfigure(1, weight=1)
930
+ self.browse = ttk.Button( button_frame, text='Browse', command=self.choose,
931
+ default='active')
932
+ self.browse.grid(row=0, column=0, sticky=Tk_.E, padx=6)
933
+ button = ttk.Button(button_frame, text='Cancel', command=self.cancel)
934
+ button.grid(row=0, column=1, sticky=Tk_.W, padx=6)
935
+ button_frame.pack(pady=6, fill=Tk_.BOTH, expand=1)
936
+ self.root.protocol('WM_DELETE_WINDOW', self.cancel)
937
+ try:
938
+ _place_window(self.root, parent)
939
+ except AttributeError:
940
+ self._set_transient(container)
941
+ degree_var.set('2')
942
+ cyclic_var.set(True)
943
+ self.show_covers()
944
+ degree_var.trace_add('write', self.show_covers)
945
+ cyclic_var.trace_add('write', self.show_covers)
946
+
947
+
948
+ def clear_list(self, *args):
949
+ self.covers.delete(*self.covers.get_children())
950
+ self.browse.config(default='normal')
951
+ self.state = 'not ready'
952
+
953
+ def show_covers(self, *args):
954
+ self.state = 'ready'
955
+ self.browse.config(default='active')
956
+ self.covers.delete(*self.covers.get_children())
957
+ degree = int(self.degree_var.get())
958
+ if self.cyclic_var.get():
959
+ self.cover_list = self.manifold.covers(
960
+ degree, cover_type='cyclic')
961
+ else:
962
+ self.cover_list = self.manifold.covers(degree)
963
+ for n, N in enumerate(self.cover_list):
964
+ cusps = repr(N.num_cusps())
965
+ homology = repr(N.homology())
966
+ name = N.name()
967
+ cover_type = N.cover_info()['type']
968
+ self.covers.insert( '', 'end',
969
+ values=(n, cover_type, cusps, homology))
970
+
971
+ def handle_return(self, event):
972
+ if self.state == 'ready':
973
+ self.choose()
974
+ else:
975
+ self.show_covers()
976
+
977
+ def choose(self, event=None):
978
+ self.result = [self.cover_list[self.covers.index(x)]
979
+ for x in self.covers.selection()]
980
+ self.root.destroy()
981
+
982
+ def cancel(self):
983
+ self.result = []
984
+ self.root.destroy()
985
+
986
+ def go(self):
987
+ self.root.grab_set()
988
+ self.root.wait_window()
989
+
990
+
991
+ if __name__ == '__main__':
992
+ from snappy import Manifold
993
+ root = Tk_.Tk()
994
+ root.withdraw()
995
+ browser1 = Browser(Manifold('m125'), root)
996
+ browser2 = Browser(Manifold('12n345'))
997
+ root.wait_window(browser1.window)
998
+ root.wait_window(browser2.window)