snappy 3.2__cp313-cp313-macosx_11_0_arm64.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-313-darwin.so +0 -0
  2. snappy/SnapPy.cpython-313-darwin.so +0 -0
  3. snappy/SnapPy.ico +0 -0
  4. snappy/SnapPy.png +0 -0
  5. snappy/SnapPyHP.cpython-313-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-313-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
@@ -0,0 +1,351 @@
1
+ from . import constants
2
+ from . import epsilons
3
+ from . import exceptions
4
+
5
+ from ..snap.t3mlite import simplex, Tetrahedron, Mcomplex # type: ignore
6
+
7
+ from ..hyperboloid import r13_dot # type: ignore
8
+ from ..geometric_structure.geodesic.geodesic_start_point_info import GeodesicStartPointInfo
9
+ from ..geometric_structure.geodesic.line import R13LineWithMatrix
10
+ from ..geometric_structure.geodesic.check_away_from_core_curve import check_away_from_core_curve
11
+ from ..exceptions import InsufficientPrecisionError # type: ignore
12
+
13
+ from typing import Sequence, Optional, List
14
+
15
+
16
+ class Endpoint:
17
+ """
18
+ Used to represent an endpoint of a line segment in a tetrahedron
19
+ in the hyperboloid model.
20
+
21
+ That is, a pair of an (unnormalised) time vector and a t3mlite' style
22
+ subsimplex saying whether the point is a vertex, on a face or in the
23
+ interior of the tetrahedron.
24
+ """
25
+
26
+ def __init__(self,
27
+ r13_point, # Unnormalised time vector
28
+ subsimplex : int): # t3mlite' style vertex, face, simplex.T
29
+ self.r13_point = r13_point
30
+ self.subsimplex : int = subsimplex
31
+
32
+ def __repr__(self):
33
+ return "Endpoint(%r, %r)" % (self.r13_point, self.subsimplex)
34
+
35
+
36
+ class GeodesicPiece:
37
+ """
38
+ A line segment in a tetrahedron that can participate in a linked list
39
+ (via prev and next_) to make a loop.
40
+
41
+ The line segment is going from endpoints[0] to endpoints[1] of the
42
+ given tetrahedron tet such that endpoints[1] of this piece matches
43
+ endpoints[0] of the next piece (in, probably, a different tetrahedron).
44
+
45
+ There is an additional field index that can be used by clients for
46
+ book-keeping purposes, for example, to store the index of the cusp
47
+ obtained by drilling this geodesic.
48
+ """
49
+
50
+ def __init__(self,
51
+ index : Optional[int],
52
+ tet : Tetrahedron,
53
+ endpoints : Sequence[Endpoint]):
54
+ self.index : Optional[int] = index
55
+ self.tet : Tetrahedron = tet
56
+ self.endpoints : Sequence[Endpoint] = endpoints
57
+ self.prev = None
58
+ self.next_ = None
59
+ self.tracker = None
60
+
61
+ @staticmethod
62
+ def create_and_attach(index : int,
63
+ tet : Tetrahedron,
64
+ endpoints : Sequence[Endpoint]):
65
+ """
66
+ Creates a line segment and appends it to tet.geodesic_pieces.
67
+ """
68
+ g = GeodesicPiece(index, tet, endpoints)
69
+ tet.geodesic_pieces.append(g)
70
+ return g
71
+
72
+ @staticmethod
73
+ def create_face_to_vertex_and_attach(index : int,
74
+ tet : Tetrahedron,
75
+ point : Endpoint,
76
+ direction : int):
77
+ """
78
+ Creates a line segment between the given endpoint on
79
+ a face and the opposite vertex. If direction is +1,
80
+ the pieces goes from the endpoint to the vertex.
81
+ If direction is -1, it goes the opposite way.
82
+
83
+ Also appends the new geodesic piece to tet.geodesic_pieces.
84
+ """
85
+ if point.subsimplex not in simplex.TwoSubsimplices:
86
+ raise ValueError(
87
+ "Expected point to be on a face, but its "
88
+ "subsimplex is %d" % point.subsimplex)
89
+ v = simplex.comp(point.subsimplex)
90
+ return GeodesicPiece.create_and_attach(
91
+ index,
92
+ tet,
93
+ [ point,
94
+ Endpoint(tet.R13_vertices[v], v) ][::direction])
95
+
96
+ @staticmethod
97
+ def make_linked_list(pieces):
98
+ """
99
+ Given a list of pieces, populates next_ and prev of each
100
+ piece to turn it into a linked list.
101
+ """
102
+
103
+ n = len(pieces)
104
+ for i in range(n):
105
+ a = pieces[i]
106
+ b = pieces[(i+1) % n]
107
+ a.next_ = b
108
+ b.prev = a
109
+
110
+ def is_face_to_vertex(self) -> bool:
111
+ """
112
+ True if line segment starts on a face and goes to a vertex.
113
+ """
114
+
115
+ return (
116
+ (self.endpoints[0].subsimplex in simplex.TwoSubsimplices) and
117
+ (self.endpoints[1].subsimplex in simplex.ZeroSubsimplices))
118
+
119
+ @staticmethod
120
+ def replace_by(start_piece, end_piece, pieces) -> None:
121
+ """
122
+ Replaces the pieces between start_piece and end_piece (inclusive)
123
+ by the given (not linked) list of pieces in the linked list that
124
+ start_piece and end_piece participate in.
125
+ """
126
+ if start_piece.prev is end_piece:
127
+ items = pieces + [ pieces[0] ]
128
+ else:
129
+ items = [ start_piece.prev ] + pieces + [ end_piece.next_ ]
130
+ for i in range(len(items) - 1):
131
+ a = items[i]
132
+ b = items[i + 1]
133
+ a.next_ = b
134
+ b.prev = a
135
+ for piece in [ start_piece, end_piece ]:
136
+ if piece.tracker:
137
+ piece.tracker.set_geodesic_piece(pieces[0])
138
+ break
139
+
140
+ def __repr__(self):
141
+ return "GeodesicPiece(%d, %r, %r)" % (self.index, self.tet, self.endpoints)
142
+
143
+
144
+ class GeodesicPieceTracker:
145
+ def __init__(self, geodesic_piece):
146
+ self.set_geodesic_piece(geodesic_piece)
147
+
148
+ def set_geodesic_piece(self, geodesic_piece):
149
+ self.geodesic_piece = geodesic_piece
150
+ geodesic_piece.tracker = self
151
+
152
+
153
+ def compute_plane_intersection_param(
154
+ plane, # Unnormalised space-like vector/plane equation
155
+ point, # Unnormalised time-like vector
156
+ direction, # Unnormalised space-like vector
157
+ verified : bool):
158
+ """
159
+ Compute for which p the ray point + p * direction intersects the
160
+ given plane, that is r13_dot(plane, point + p * direction) = 0.
161
+
162
+ Note that when verified is true and intervals are given, only the
163
+ positive possible values will be returned. That is, if the direction
164
+ lies in the plane or is close to lying in the plane, the possible
165
+ values are of the form (-inf, a) and (b, inf). In this case, the function
166
+ returns the interval (b, inf) rather than (-inf, inf).
167
+ """
168
+
169
+ num = -r13_dot(plane, point)
170
+ denom = r13_dot(plane, direction)
171
+
172
+ # Avoid division by zero differently for numbers and intervals.
173
+ if verified:
174
+ # Note that this is not equivalent to denom == 0!
175
+ if not denom != 0:
176
+ # The case we described above.
177
+ # Unless the num interval contained zero,
178
+ # abs(num) is an interval [a, b] with a > 0.
179
+ # abs(denom) returns an interval of the form [0, x].
180
+ # The quotient [a, b] / [0, x] is of the form [t, inf) with t > 0.
181
+ return abs(num) / abs(denom)
182
+ else:
183
+ if denom == 0:
184
+ # Not verified: just make denom something very small rather than
185
+ # zero.
186
+ RF = denom.parent()
187
+ denom = RF(1e-200)
188
+
189
+ return num / denom
190
+
191
+
192
+ def trace_geodesic(geodesic : GeodesicStartPointInfo, verified : bool):
193
+ """
194
+ Traces line segment through the tetrahedra in the hyperboloid
195
+ model (though using time-like but not necessarily unit time-like vectors)
196
+ starting from the given start point in the given tetrahdra
197
+ to the given end point (assumed to be related to the start point
198
+ by a primitive Decktransformation).
199
+
200
+ The output is a (python) list of GeodesicPiece's (that is also
201
+ a cyclic linked list). The first piece is going from the interior of a
202
+ tetrahedron to a point on the face of the tetrahedron. The last piece
203
+ goes the other way to close the loop. All other pieces go from a
204
+ point on a face to a point on another face.
205
+
206
+ If geodesic.line is set, it also checks that the geodesic is not
207
+ too close to a core curve.
208
+ """
209
+
210
+ obj_name = "Geodesic %s" % geodesic.word
211
+
212
+ if geodesic.tet is None:
213
+ raise ValueError(
214
+ "Expected geodesic with tetrahedron to start tracing.")
215
+
216
+ # start_point and direction forming the ray we are tracing.
217
+ # Note that we apply the face-pairing matrices to the ray when we go
218
+ # from one tetrahedron to the next, but we do not move the
219
+ # start_point "forward" when we trace from one face to the next face.
220
+ start_point = geodesic.unnormalised_start_point
221
+ direction = (
222
+ geodesic.unnormalised_end_point - geodesic.unnormalised_start_point)
223
+ # Line object transformed similarly. Used to check whether geodesic
224
+ # is too close to a core curve.
225
+ line : Optional[R13LineWithMatrix] = geodesic.line
226
+
227
+ # Tetrahedron we start at.
228
+ tet : Tetrahedron = geodesic.tet
229
+ # Set face to simplex.T to indicate we start in the interior of the tet.
230
+ face : int = simplex.T
231
+
232
+ RF = start_point[0].parent()
233
+
234
+ if verified:
235
+ epsilon = 0
236
+ else:
237
+ epsilon = epsilons.compute_epsilon(RF)
238
+
239
+ # Result
240
+ pieces : List[GeodesicPiece] = [ ]
241
+
242
+ # Parametrizes ray. That is, we are start_point + param * direction.
243
+ param = RF(0)
244
+
245
+ # Trace
246
+ for i in range(constants.trace_max_steps):
247
+ # Record the face and param through which the ray is leaving
248
+ # the tet - that is which face the ray is hitting next.
249
+ hit_face : Optional[int] = None
250
+ hit_param = None
251
+ for candidate_face, plane in tet.R13_unnormalised_planes.items():
252
+ # Skip the face through which the ray just entered the tet
253
+ if candidate_face == face:
254
+ continue
255
+ # Compute the param at which the ray intersects this face
256
+ candidate_param = compute_plane_intersection_param(
257
+ plane, start_point, direction, verified)
258
+
259
+ # If the ray crossed this face before it crossed the
260
+ # entry face, ignore. Can happen when a dihedral angle is obtuse.
261
+ if candidate_param < param - epsilon:
262
+ continue
263
+ if not candidate_param > param + epsilon:
264
+ raise InsufficientPrecisionError(
265
+ "When tracing the geodesic, the intersection with the "
266
+ "next tetrahedron face was too close to the previous "
267
+ "to tell them apart. Increasing the precision will "
268
+ "probably avoid this problem.")
269
+
270
+ # This face is the (potential) exit face if the ray crossed
271
+ # it before it crossed the other faces (encountered so far).
272
+
273
+ if hit_param is None:
274
+ # No other face encountered so far
275
+ hit_param = candidate_param
276
+ hit_face = candidate_face
277
+ else:
278
+ # Check this face crossed before other faces
279
+ if candidate_param + epsilon < hit_param:
280
+ hit_param = candidate_param
281
+ hit_face = candidate_face
282
+ elif not candidate_param > hit_param + epsilon:
283
+ # If there is any ambiguity whether this face was
284
+ # crossed before the other face, fail!
285
+ # Most likely, this is because the ray is close to
286
+ # or crossing an edge of the triangulation.
287
+ raise exceptions.RayHittingOneSkeletonError()
288
+
289
+ if hit_param is None or hit_face is None:
290
+ raise InsufficientPrecisionError(
291
+ "Could not find the next intersection of the geodesic with a "
292
+ "tetrahedron face. Increasing the precision should solve this "
293
+ "problem.")
294
+
295
+ # Check geodesic does not intersect core curve - if line is given.
296
+ if line is not None:
297
+ check_away_from_core_curve(
298
+ line.r13_line, tet, hit_face, epsilon, obj_name)
299
+
300
+ # The crossing of the ray with the exit face is beyond the given
301
+ # end point. Thus, we are at the last piece.
302
+ if hit_param > RF(1) + epsilon:
303
+ # Force us to end at the given end point
304
+ hit_param = RF(1)
305
+ # The last piece ends in the interior of a tetrahedron.
306
+ T : int = simplex.T # Make mypy happy.
307
+ hit_face = T
308
+ elif not hit_param < RF(1) - epsilon:
309
+ raise InsufficientPrecisionError(
310
+ "Could not determine whether we finished tracing the geodesic. "
311
+ "Increasing the precision will most likely fix the "
312
+ "problem.")
313
+
314
+ pieces.append(
315
+ GeodesicPiece(
316
+ geodesic.index,
317
+ tet,
318
+ [Endpoint(start_point + param * direction, face),
319
+ Endpoint(start_point + hit_param * direction, hit_face)]))
320
+
321
+ if hit_face == simplex.T:
322
+ if tet is not geodesic.tet:
323
+ raise InsufficientPrecisionError(
324
+ "Tracing geodesic ended up in a different "
325
+ "tetrahedron than it started. "
326
+ "Increasing the precision will probably fix this problem.")
327
+
328
+ GeodesicPiece.make_linked_list(pieces)
329
+
330
+ return pieces
331
+
332
+ # Face-pairing matrix to transform data from this tetrahedron
333
+ # to next tetrahedron.
334
+ m = tet.O13_matrices[hit_face]
335
+
336
+ # Transform data
337
+ start_point = m * start_point
338
+ direction = m * direction
339
+ if line is not None:
340
+ line = line.transformed(m)
341
+ param = hit_param
342
+
343
+ # Determine what the entry face of the next tetrahedron is
344
+ face = tet.Gluing[hit_face].image(hit_face)
345
+
346
+ # The next tetrahedron - set last because we used it when
347
+ # computing face.
348
+ tet = tet.Neighbor[hit_face]
349
+
350
+ raise exceptions.UnfinishedTraceGeodesicError(
351
+ constants.trace_max_steps)
snappy/exceptions.py ADDED
@@ -0,0 +1,26 @@
1
+ class SnapPeaFatalError(Exception):
2
+ """
3
+ Exception raised by SnapPy when the SnapPea kernel encounters a fatal
4
+ error.
5
+ """
6
+
7
+
8
+ class InsufficientPrecisionError(Exception):
9
+ """
10
+ Exception raised when a computation fails and is likely to succeed if
11
+ higher precision is used.
12
+ """
13
+
14
+
15
+ class NonorientableManifoldError(ValueError):
16
+ """
17
+ Exception raised when a non-orientable manifold is given to a method
18
+ only supporting orientable manifolds.
19
+ """
20
+ def __init__(self, method_name, manifold):
21
+ self.method_name = method_name
22
+ self.manifold = manifold
23
+
24
+ def __str__(self):
25
+ return ('%s only supports orientable manifolds but %s is '
26
+ 'non-orientable.') % (self.method_name, self.manifold)
snappy/export_stl.py ADDED
@@ -0,0 +1,120 @@
1
+ import math
2
+
3
+
4
+ def facet_stl(triangle):
5
+ vertex1, vertex2, vertex3 = triangle
6
+ a = (vertex3[0]-vertex1[0], vertex3[1]-vertex1[1], vertex3[2]-vertex1[2])
7
+ b = (vertex2[0]-vertex1[0], vertex2[1]-vertex1[1], vertex2[2]-vertex1[2])
8
+ normal = (a[1]*b[2] - a[2]*b[1], a[2]*b[0] - a[0]*b[2], a[0]*b[1] - a[1]*b[0])
9
+ return ''.join([
10
+ ' facet normal %f %f %f\n' % tuple(normal),
11
+ ' outer loop\n',
12
+ ' vertex %f %f %f\n' % tuple(vertex1),
13
+ ' vertex %f %f %f\n' % tuple(vertex2),
14
+ ' vertex %f %f %f\n' % tuple(vertex3),
15
+ ' endloop\n',
16
+ ' endfacet\n'
17
+ ])
18
+
19
+
20
+ def subdivide_triangles(triangles, num_subdivisions):
21
+ if num_subdivisions == 0:
22
+ for triangle in triangles:
23
+ yield triangle
24
+ elif num_subdivisions == 1:
25
+ # A small function for getting the midpoint of two points.
26
+ midpoint = lambda P, Q: ((P[0] + Q[0]) / 2, (P[1] + Q[1]) / 2, (P[2] + Q[2]) / 2)
27
+ for (x, y, z) in triangles:
28
+ yield (x, midpoint(x, y), midpoint(x, z))
29
+ yield (midpoint(y, x), y, midpoint(y, z))
30
+ yield (midpoint(z, x), midpoint(z, y), z)
31
+ yield (midpoint(x, y), midpoint(y, z), midpoint(z, x))
32
+ else:
33
+ for triangle in subdivide_triangles(subdivide_triangles(triangles, 1), num_subdivisions - 1):
34
+ yield triangle
35
+ return
36
+
37
+
38
+ def projection(triangle, cutoff_radius):
39
+ ''' Return the projection of a point in the Klein model to the Poincare model. '''
40
+ x, y, z = triangle
41
+ scale = min(1 / (1 + math.sqrt(max(0, 1 - (x**2 + y**2 + z**2)))), cutoff_radius)
42
+ return (scale*x, scale*y, scale*z)
43
+
44
+
45
+ def klein_stl(face_dicts):
46
+ ''' Yield triangles describing these faces. '''
47
+ for face in face_dicts:
48
+ vertices = face['vertices']
49
+ for i in range(len(vertices)-2):
50
+ yield (vertices[0], vertices[i+1], vertices[i+2])
51
+ return
52
+
53
+
54
+ def klein_cutout_stl(face_dicts, shrink_factor=0.9):
55
+ ''' Yield triangles describing these faces after removing a fraction of the interior.
56
+
57
+ The fraction removed is given by shrink_factor. '''
58
+ for face in face_dicts:
59
+ vertices = face['vertices']
60
+ center = [sum(vertex[i] for vertex in vertices) / len(vertices) for i in range(3)]
61
+ new_vertices = [[vertex[i] + (center[i] - vertex[i]) / 3 for i in range(3)] for vertex in vertices]
62
+ new_inside_points = [[point[i] * shrink_factor for i in range(3)] for point in new_vertices]
63
+ for i in range(len(new_vertices)):
64
+ yield (new_vertices[i], new_inside_points[(i+1) % len(new_vertices)], new_inside_points[i])
65
+ yield (new_vertices[i], new_vertices[(i+1) % len(new_vertices)], new_inside_points[(i+1) % len(new_vertices)])
66
+ yield (vertices[i], new_vertices[(i+1) % len(vertices)], new_vertices[i])
67
+ yield (vertices[i], vertices[(i+1) % len(vertices)], new_vertices[(i+1) % len(vertices)])
68
+ # We have to go in the opposite direction this time as the normal should point in towards O.
69
+ yield tuple(tuple(shrink_factor * coord for coord in point) for point in (vertices[i], new_vertices[i], new_vertices[(i+1) % len(vertices)]))
70
+ yield tuple(tuple(shrink_factor * coord for coord in point) for point in (vertices[i], new_vertices[(i+1) % len(vertices)], vertices[(i+1) % len(vertices)]))
71
+ return
72
+
73
+
74
+ def poincare_stl(face_dicts, num_subdivisions=5, cutoff_radius=0.9):
75
+ ''' Yield the output of klein_stl(face_dicts, ...) after applying projection to every vertex produced. '''
76
+ for triangle in subdivide_triangles(klein_stl(face_dicts), num_subdivisions):
77
+ yield (projection(triangle[0], cutoff_radius), projection(triangle[1], cutoff_radius), projection(triangle[2], cutoff_radius))
78
+ return
79
+
80
+
81
+ def poincare_cutout_stl(face_dicts, num_subdivisions=3, shrink_factor=0.9, cutoff_radius=0.9):
82
+ ''' Yield the output of klein_cutout_stl(face_dicts, ...) after applying projection to every vertex produced. '''
83
+ for triangle in subdivide_triangles(klein_cutout_stl(face_dicts, shrink_factor), num_subdivisions):
84
+ yield (projection(triangle[0], cutoff_radius), projection(triangle[1], cutoff_radius), projection(triangle[2], cutoff_radius))
85
+ return
86
+
87
+
88
+ def stl(face_dicts, model='klein', cutout=False, num_subdivisions=3, shrink_factor=0.9, cutoff_radius=0.9):
89
+ """
90
+ Yield the lines of an stl file corresponding to the solid given by face_dicts that is suitable for 3d printing.
91
+
92
+ Arguments can be given to modify the model produced:
93
+
94
+ - model='klein' -- (alt. 'poincare') the model of HH^3 to use.
95
+ - cutout=False -- remove the interior of each face
96
+ - shrink_factor=0.9 -- the fraction to cut out of each face
97
+ - cuttoff_radius=0.9 -- maximum rescaling for projection into Poincaré model
98
+ - num_subdivision=3 -- number of times to subdivide for the Poincaré model
99
+
100
+ For printing domains in the Poincaré model, cutoff_radius is
101
+ critical for avoiding infinitely thin cusps, which cannot be printed.
102
+ """
103
+ if shrink_factor < 0 or shrink_factor > 1:
104
+ raise ValueError('shrink_factor must be between 0 and 1.')
105
+
106
+ if model == 'klein' and cutout:
107
+ output = klein_cutout_stl(face_dicts, shrink_factor=shrink_factor)
108
+ elif model == 'klein' and not cutout:
109
+ output = klein_stl(face_dicts)
110
+ elif model == 'poincare' and cutout:
111
+ output = poincare_cutout_stl(face_dicts, num_subdivisions=num_subdivisions, shrink_factor=shrink_factor, cutoff_radius=cutoff_radius)
112
+ elif model == 'poincare' and not cutout:
113
+ output = poincare_stl(face_dicts, num_subdivisions=num_subdivisions, cutoff_radius=cutoff_radius)
114
+ else:
115
+ raise ValueError('Unknown model. Known models: \'klein\' and \'poincare\'.')
116
+
117
+ yield 'solid\n'
118
+ for triangle in output:
119
+ yield facet_stl(triangle)
120
+ yield 'endsolid\n'
@@ -0,0 +1,2 @@
1
+ from .main import exterior_to_link
2
+ from .exceptions import ExteriorToLinkError, GeneralPositionError