snappy 3.3__cp310-cp310-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- snappy/CyOpenGL.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/SnapPy.ico +0 -0
- snappy/SnapPy.png +0 -0
- snappy/SnapPyHP.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/__init__.py +534 -0
- snappy/app.py +604 -0
- snappy/app_menus.py +372 -0
- snappy/browser.py +998 -0
- snappy/cache.py +25 -0
- snappy/canonical.py +249 -0
- snappy/cusps/__init__.py +280 -0
- snappy/cusps/cusp_area_matrix.py +98 -0
- snappy/cusps/cusp_areas_from_matrix.py +96 -0
- snappy/cusps/maximal_cusp_area_matrix.py +136 -0
- snappy/cusps/short_slopes_for_cusp.py +217 -0
- snappy/cusps/test.py +22 -0
- snappy/cusps/trig_cusp_area_matrix.py +63 -0
- snappy/database.py +454 -0
- snappy/db_utilities.py +79 -0
- snappy/decorated_isosig.py +717 -0
- snappy/dev/__init__.py +0 -0
- snappy/dev/extended_ptolemy/__init__.py +8 -0
- snappy/dev/extended_ptolemy/closed.py +106 -0
- snappy/dev/extended_ptolemy/complexVolumesClosed.py +149 -0
- snappy/dev/extended_ptolemy/direct.py +42 -0
- snappy/dev/extended_ptolemy/extended.py +406 -0
- snappy/dev/extended_ptolemy/giac_helper.py +43 -0
- snappy/dev/extended_ptolemy/giac_rur.py +129 -0
- snappy/dev/extended_ptolemy/gluing.py +46 -0
- snappy/dev/extended_ptolemy/phc_wrapper.py +220 -0
- snappy/dev/extended_ptolemy/printMatrices.py +70 -0
- snappy/dev/vericlosed/__init__.py +1 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureNew.py +159 -0
- snappy/dev/vericlosed/computeApproxHyperbolicStructureOrb.py +90 -0
- snappy/dev/vericlosed/computeVerifiedHyperbolicStructure.py +111 -0
- snappy/dev/vericlosed/gimbalLoopFinder.py +130 -0
- snappy/dev/vericlosed/hyperbolicStructure.py +313 -0
- snappy/dev/vericlosed/krawczykCertifiedEdgeLengthsEngine.py +165 -0
- snappy/dev/vericlosed/oneVertexTruncatedComplex.py +122 -0
- snappy/dev/vericlosed/orb/__init__.py +1 -0
- snappy/dev/vericlosed/orb/orb_solution_for_snappea_finite_triangulation_mac +0 -0
- snappy/dev/vericlosed/parseVertexGramMatrixFile.py +47 -0
- snappy/dev/vericlosed/polishApproxHyperbolicStructure.py +61 -0
- snappy/dev/vericlosed/test.py +54 -0
- snappy/dev/vericlosed/truncatedComplex.py +176 -0
- snappy/dev/vericlosed/verificationError.py +58 -0
- snappy/dev/vericlosed/verifyHyperbolicStructureEngine.py +177 -0
- snappy/doc/_images/SnapPy-196.png +0 -0
- snappy/doc/_images/m004_paper_plane_on_systole.jpg +0 -0
- snappy/doc/_images/m125_paper_plane.jpg +0 -0
- snappy/doc/_images/mac.png +0 -0
- snappy/doc/_images/o9_00000_systole_paper_plane.jpg +0 -0
- snappy/doc/_images/o9_00000_systole_paper_plane_closer.jpg +0 -0
- snappy/doc/_images/plink-action.png +0 -0
- snappy/doc/_images/ubuntu.png +0 -0
- snappy/doc/_images/win7.png +0 -0
- snappy/doc/_sources/additional_classes.rst.txt +40 -0
- snappy/doc/_sources/bugs.rst.txt +14 -0
- snappy/doc/_sources/censuses.rst.txt +52 -0
- snappy/doc/_sources/credits.rst.txt +81 -0
- snappy/doc/_sources/development.rst.txt +261 -0
- snappy/doc/_sources/index.rst.txt +215 -0
- snappy/doc/_sources/installing.rst.txt +249 -0
- snappy/doc/_sources/manifold.rst.txt +6 -0
- snappy/doc/_sources/manifoldhp.rst.txt +46 -0
- snappy/doc/_sources/news.rst.txt +425 -0
- snappy/doc/_sources/other.rst.txt +25 -0
- snappy/doc/_sources/platonic_census.rst.txt +20 -0
- snappy/doc/_sources/plink.rst.txt +102 -0
- snappy/doc/_sources/ptolemy.rst.txt +66 -0
- snappy/doc/_sources/ptolemy_classes.rst.txt +42 -0
- snappy/doc/_sources/ptolemy_examples1.rst.txt +298 -0
- snappy/doc/_sources/ptolemy_examples2.rst.txt +363 -0
- snappy/doc/_sources/ptolemy_examples3.rst.txt +301 -0
- snappy/doc/_sources/ptolemy_examples4.rst.txt +61 -0
- snappy/doc/_sources/ptolemy_prelim.rst.txt +105 -0
- snappy/doc/_sources/screenshots.rst.txt +21 -0
- snappy/doc/_sources/snap.rst.txt +87 -0
- snappy/doc/_sources/snappy.rst.txt +28 -0
- snappy/doc/_sources/spherogram.rst.txt +103 -0
- snappy/doc/_sources/todo.rst.txt +47 -0
- snappy/doc/_sources/triangulation.rst.txt +11 -0
- snappy/doc/_sources/tutorial.rst.txt +49 -0
- snappy/doc/_sources/verify.rst.txt +210 -0
- snappy/doc/_sources/verify_internals.rst.txt +79 -0
- snappy/doc/_static/SnapPy-horizontal-128.png +0 -0
- snappy/doc/_static/SnapPy.ico +0 -0
- snappy/doc/_static/_sphinx_javascript_frameworks_compat.js +123 -0
- snappy/doc/_static/basic.css +906 -0
- snappy/doc/_static/css/badge_only.css +1 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff +0 -0
- snappy/doc/_static/css/fonts/Roboto-Slab-Regular.woff2 +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.eot +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.svg +2671 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.ttf +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff +0 -0
- snappy/doc/_static/css/fonts/fontawesome-webfont.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff +0 -0
- snappy/doc/_static/css/fonts/lato-bold.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal-italic.woff2 +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff +0 -0
- snappy/doc/_static/css/fonts/lato-normal.woff2 +0 -0
- snappy/doc/_static/css/theme.css +4 -0
- snappy/doc/_static/doctools.js +149 -0
- snappy/doc/_static/documentation_options.js +13 -0
- snappy/doc/_static/file.png +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-bold.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-bolditalic.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-italic.woff2 +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.eot +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.ttf +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.woff +0 -0
- snappy/doc/_static/fonts/Lato/lato-regular.woff2 +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.eot +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.ttf +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-bold.woff2 +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.eot +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.ttf +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff +0 -0
- snappy/doc/_static/fonts/RobotoSlab/roboto-slab-v7-regular.woff2 +0 -0
- snappy/doc/_static/jquery.js +2 -0
- snappy/doc/_static/js/badge_only.js +1 -0
- snappy/doc/_static/js/theme.js +1 -0
- snappy/doc/_static/js/versions.js +228 -0
- snappy/doc/_static/language_data.js +192 -0
- snappy/doc/_static/minus.png +0 -0
- snappy/doc/_static/plus.png +0 -0
- snappy/doc/_static/pygments.css +75 -0
- snappy/doc/_static/searchtools.js +635 -0
- snappy/doc/_static/snappy_furo.css +33 -0
- snappy/doc/_static/snappy_sphinx_rtd_theme.css +42 -0
- snappy/doc/_static/sphinx_highlight.js +154 -0
- snappy/doc/additional_classes.html +1500 -0
- snappy/doc/bugs.html +132 -0
- snappy/doc/censuses.html +453 -0
- snappy/doc/credits.html +184 -0
- snappy/doc/development.html +385 -0
- snappy/doc/doc-latest/additional_classes.html +1500 -0
- snappy/doc/doc-latest/bugs.html +132 -0
- snappy/doc/doc-latest/censuses.html +453 -0
- snappy/doc/doc-latest/credits.html +184 -0
- snappy/doc/doc-latest/development.html +385 -0
- snappy/doc/doc-latest/genindex.html +1349 -0
- snappy/doc/doc-latest/index.html +287 -0
- snappy/doc/doc-latest/installing.html +346 -0
- snappy/doc/doc-latest/manifold.html +3632 -0
- snappy/doc/doc-latest/manifoldhp.html +180 -0
- snappy/doc/doc-latest/news.html +438 -0
- snappy/doc/doc-latest/objects.inv +0 -0
- snappy/doc/doc-latest/other.html +160 -0
- snappy/doc/doc-latest/platonic_census.html +376 -0
- snappy/doc/doc-latest/plink.html +210 -0
- snappy/doc/doc-latest/ptolemy.html +253 -0
- snappy/doc/doc-latest/ptolemy_classes.html +1144 -0
- snappy/doc/doc-latest/ptolemy_examples1.html +409 -0
- snappy/doc/doc-latest/ptolemy_examples2.html +471 -0
- snappy/doc/doc-latest/ptolemy_examples3.html +414 -0
- snappy/doc/doc-latest/ptolemy_examples4.html +195 -0
- snappy/doc/doc-latest/ptolemy_prelim.html +248 -0
- snappy/doc/doc-latest/py-modindex.html +165 -0
- snappy/doc/doc-latest/screenshots.html +141 -0
- snappy/doc/doc-latest/search.html +135 -0
- snappy/doc/doc-latest/searchindex.js +1 -0
- snappy/doc/doc-latest/snap.html +202 -0
- snappy/doc/doc-latest/snappy.html +181 -0
- snappy/doc/doc-latest/spherogram.html +1346 -0
- snappy/doc/doc-latest/todo.html +166 -0
- snappy/doc/doc-latest/triangulation.html +1676 -0
- snappy/doc/doc-latest/tutorial.html +159 -0
- snappy/doc/doc-latest/verify.html +330 -0
- snappy/doc/doc-latest/verify_internals.html +1235 -0
- snappy/doc/genindex.html +1349 -0
- snappy/doc/index.html +287 -0
- snappy/doc/installing.html +346 -0
- snappy/doc/manifold.html +3632 -0
- snappy/doc/manifoldhp.html +180 -0
- snappy/doc/news.html +438 -0
- snappy/doc/objects.inv +0 -0
- snappy/doc/other.html +160 -0
- snappy/doc/platonic_census.html +376 -0
- snappy/doc/plink.html +210 -0
- snappy/doc/ptolemy.html +253 -0
- snappy/doc/ptolemy_classes.html +1144 -0
- snappy/doc/ptolemy_examples1.html +409 -0
- snappy/doc/ptolemy_examples2.html +471 -0
- snappy/doc/ptolemy_examples3.html +414 -0
- snappy/doc/ptolemy_examples4.html +195 -0
- snappy/doc/ptolemy_prelim.html +248 -0
- snappy/doc/py-modindex.html +165 -0
- snappy/doc/screenshots.html +141 -0
- snappy/doc/search.html +135 -0
- snappy/doc/searchindex.js +1 -0
- snappy/doc/snap.html +202 -0
- snappy/doc/snappy.html +181 -0
- snappy/doc/spherogram.html +1346 -0
- snappy/doc/todo.html +166 -0
- snappy/doc/triangulation.html +1676 -0
- snappy/doc/tutorial.html +159 -0
- snappy/doc/verify.html +330 -0
- snappy/doc/verify_internals.html +1235 -0
- snappy/drilling/__init__.py +456 -0
- snappy/drilling/barycentric.py +103 -0
- snappy/drilling/constants.py +5 -0
- snappy/drilling/crush.py +270 -0
- snappy/drilling/cusps.py +125 -0
- snappy/drilling/debug.py +242 -0
- snappy/drilling/epsilons.py +6 -0
- snappy/drilling/exceptions.py +55 -0
- snappy/drilling/moves.py +620 -0
- snappy/drilling/peripheral_curves.py +210 -0
- snappy/drilling/perturb.py +188 -0
- snappy/drilling/shorten.py +36 -0
- snappy/drilling/subdivide.py +274 -0
- snappy/drilling/test.py +23 -0
- snappy/drilling/test_cases.py +132 -0
- snappy/drilling/tracing.py +351 -0
- snappy/exceptions.py +26 -0
- snappy/export_stl.py +120 -0
- snappy/exterior_to_link/__init__.py +2 -0
- snappy/exterior_to_link/barycentric_geometry.py +463 -0
- snappy/exterior_to_link/exceptions.py +6 -0
- snappy/exterior_to_link/geodesic_map.json +14408 -0
- snappy/exterior_to_link/hyp_utils.py +112 -0
- snappy/exterior_to_link/link_projection.py +323 -0
- snappy/exterior_to_link/main.py +198 -0
- snappy/exterior_to_link/mcomplex_with_expansion.py +261 -0
- snappy/exterior_to_link/mcomplex_with_link.py +687 -0
- snappy/exterior_to_link/mcomplex_with_memory.py +162 -0
- snappy/exterior_to_link/pl_utils.py +491 -0
- snappy/exterior_to_link/put_in_S3.py +156 -0
- snappy/exterior_to_link/rational_linear_algebra.py +130 -0
- snappy/exterior_to_link/rational_linear_algebra_wrapped.py +135 -0
- snappy/exterior_to_link/simplify_to_base_tri.py +114 -0
- snappy/exterior_to_link/stored_moves.py +475 -0
- snappy/exterior_to_link/test.py +31 -0
- snappy/filedialog.py +28 -0
- snappy/geometric_structure/__init__.py +212 -0
- snappy/geometric_structure/cusp_neighborhood/__init__.py +3 -0
- snappy/geometric_structure/cusp_neighborhood/complex_cusp_cross_section.py +691 -0
- snappy/geometric_structure/cusp_neighborhood/cusp_cross_section_base.py +480 -0
- snappy/geometric_structure/cusp_neighborhood/exceptions.py +41 -0
- snappy/geometric_structure/cusp_neighborhood/real_cusp_cross_section.py +294 -0
- snappy/geometric_structure/cusp_neighborhood/tiles_for_cusp_neighborhood.py +156 -0
- snappy/geometric_structure/cusp_neighborhood/vertices.py +35 -0
- snappy/geometric_structure/geodesic/__init__.py +0 -0
- snappy/geometric_structure/geodesic/add_core_curves.py +152 -0
- snappy/geometric_structure/geodesic/avoid_core_curves.py +369 -0
- snappy/geometric_structure/geodesic/canonical_representatives.py +52 -0
- snappy/geometric_structure/geodesic/check_away_from_core_curve.py +60 -0
- snappy/geometric_structure/geodesic/constants.py +6 -0
- snappy/geometric_structure/geodesic/exceptions.py +22 -0
- snappy/geometric_structure/geodesic/fixed_points.py +106 -0
- snappy/geometric_structure/geodesic/geodesic_start_point_info.py +435 -0
- snappy/geometric_structure/geodesic/graph_trace_helper.py +67 -0
- snappy/geometric_structure/geodesic/line.py +30 -0
- snappy/geometric_structure/geodesic/multiplicity.py +127 -0
- snappy/geometric_structure/geodesic/tiles_for_geodesic.py +128 -0
- snappy/geometric_structure/test.py +22 -0
- snappy/gui.py +121 -0
- snappy/horoviewer.py +443 -0
- snappy/hyperboloid/__init__.py +212 -0
- snappy/hyperboloid/distances.py +259 -0
- snappy/hyperboloid/horoball.py +19 -0
- snappy/hyperboloid/line.py +35 -0
- snappy/hyperboloid/point.py +9 -0
- snappy/hyperboloid/triangle.py +29 -0
- snappy/info_icon.gif +0 -0
- snappy/infowindow.py +65 -0
- snappy/isometry_signature.py +389 -0
- snappy/len_spec/__init__.py +609 -0
- snappy/len_spec/geodesic_info.py +129 -0
- snappy/len_spec/geodesic_key_info_dict.py +116 -0
- snappy/len_spec/geodesic_piece.py +146 -0
- snappy/len_spec/geometric_structure.py +182 -0
- snappy/len_spec/geometry.py +136 -0
- snappy/len_spec/length_spectrum_geodesic_info.py +185 -0
- snappy/len_spec/spine.py +128 -0
- snappy/len_spec/test.py +24 -0
- snappy/len_spec/test_cases.py +69 -0
- snappy/len_spec/tile.py +276 -0
- snappy/len_spec/word.py +86 -0
- snappy/manifolds/HTWKnots/alternating.gz +0 -0
- snappy/manifolds/HTWKnots/nonalternating.gz +0 -0
- snappy/manifolds/__init__.py +3 -0
- snappy/margulis/__init__.py +332 -0
- snappy/margulis/cusp_neighborhood_neighborhood.py +66 -0
- snappy/margulis/geodesic_neighborhood.py +152 -0
- snappy/margulis/margulis_info.py +21 -0
- snappy/margulis/mu_from_neighborhood_pair.py +175 -0
- snappy/margulis/neighborhood.py +29 -0
- snappy/margulis/test.py +22 -0
- snappy/math_basics.py +187 -0
- snappy/matrix.py +525 -0
- snappy/number.py +657 -0
- snappy/numeric_output_checker.py +345 -0
- snappy/pari.py +41 -0
- snappy/phone_home.py +57 -0
- snappy/polyviewer.py +259 -0
- snappy/ptolemy/__init__.py +17 -0
- snappy/ptolemy/component.py +103 -0
- snappy/ptolemy/coordinates.py +2290 -0
- snappy/ptolemy/fieldExtensions.py +153 -0
- snappy/ptolemy/findLoops.py +473 -0
- snappy/ptolemy/geometricRep.py +59 -0
- snappy/ptolemy/homology.py +165 -0
- snappy/ptolemy/magma/default.magma_template +229 -0
- snappy/ptolemy/magma/radicalsOfPrimaryDecomposition.magma_template +79 -0
- snappy/ptolemy/manifoldMethods.py +395 -0
- snappy/ptolemy/matrix.py +350 -0
- snappy/ptolemy/numericalSolutionsToGroebnerBasis.py +113 -0
- snappy/ptolemy/polynomial.py +856 -0
- snappy/ptolemy/processComponents.py +173 -0
- snappy/ptolemy/processFileBase.py +247 -0
- snappy/ptolemy/processFileDispatch.py +46 -0
- snappy/ptolemy/processMagmaFile.py +392 -0
- snappy/ptolemy/processRurFile.py +150 -0
- snappy/ptolemy/ptolemyGeneralizedObstructionClass.py +102 -0
- snappy/ptolemy/ptolemyObstructionClass.py +64 -0
- snappy/ptolemy/ptolemyVariety.py +995 -0
- snappy/ptolemy/ptolemyVarietyPrimeIdealGroebnerBasis.py +140 -0
- snappy/ptolemy/reginaWrapper.py +698 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/regina_testing_files_generalized/m015__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/rur.py +545 -0
- snappy/ptolemy/solutionsToPrimeIdealGroebnerBasis.py +277 -0
- snappy/ptolemy/test.py +1126 -0
- snappy/ptolemy/testing_files/3_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/3_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/4_1__sl4_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/5_2__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/DT_mcbbiceaibjklmdfgh__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c0.magma_out +95 -0
- snappy/ptolemy/testing_files/data/pgl2/OrientableCuspedCensus/03_tetrahedra/m019__sl2_c1.magma_out +95 -0
- snappy/ptolemy/testing_files/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c4.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c5.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c6.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/m135__sl2_c7.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/s000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/t00000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c2.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files/v0000__sl2_c3.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m003__sl3_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m004__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl2_c1.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_generalized/m015__sl3_c0.magma_out.bz2 +0 -0
- snappy/ptolemy/testing_files_rur/m052__sl3_c0.rur.bz2 +0 -0
- snappy/ptolemy/utilities.py +236 -0
- snappy/raytracing/__init__.py +64 -0
- snappy/raytracing/additional_horospheres.py +64 -0
- snappy/raytracing/additional_len_spec_choices.py +63 -0
- snappy/raytracing/cohomology_fractal.py +197 -0
- snappy/raytracing/eyeball.py +124 -0
- snappy/raytracing/finite_raytracing_data.py +237 -0
- snappy/raytracing/finite_viewer.py +590 -0
- snappy/raytracing/geodesic_tube_info.py +174 -0
- snappy/raytracing/geodesics.py +246 -0
- snappy/raytracing/geodesics_window.py +258 -0
- snappy/raytracing/gui_utilities.py +293 -0
- snappy/raytracing/hyperboloid_navigation.py +556 -0
- snappy/raytracing/hyperboloid_utilities.py +234 -0
- snappy/raytracing/ideal_raytracing_data.py +592 -0
- snappy/raytracing/inside_viewer.py +974 -0
- snappy/raytracing/pack.py +22 -0
- snappy/raytracing/raytracing_data.py +126 -0
- snappy/raytracing/raytracing_view.py +454 -0
- snappy/raytracing/shaders/Eye.png +0 -0
- snappy/raytracing/shaders/NonGeometric.png +0 -0
- snappy/raytracing/shaders/__init__.py +101 -0
- snappy/raytracing/shaders/fragment.glsl +1744 -0
- snappy/raytracing/test.py +29 -0
- snappy/raytracing/tooltip.py +146 -0
- snappy/raytracing/upper_halfspace_utilities.py +98 -0
- snappy/raytracing/view_scale_controller.py +98 -0
- snappy/raytracing/zoom_slider/__init__.py +263 -0
- snappy/raytracing/zoom_slider/inward.png +0 -0
- snappy/raytracing/zoom_slider/inward18.png +0 -0
- snappy/raytracing/zoom_slider/outward.png +0 -0
- snappy/raytracing/zoom_slider/outward18.png +0 -0
- snappy/raytracing/zoom_slider/test.py +20 -0
- snappy/sage_helper.py +119 -0
- snappy/settings.py +407 -0
- snappy/shell.py +53 -0
- snappy/snap/__init__.py +117 -0
- snappy/snap/character_varieties.py +375 -0
- snappy/snap/find_field.py +372 -0
- snappy/snap/fox_milnor.py +271 -0
- snappy/snap/fundamental_polyhedron.py +569 -0
- snappy/snap/generators.py +39 -0
- snappy/snap/interval_reps.py +81 -0
- snappy/snap/kernel_structures.py +128 -0
- snappy/snap/mcomplex_base.py +18 -0
- snappy/snap/nsagetools.py +716 -0
- snappy/snap/peripheral/__init__.py +1 -0
- snappy/snap/peripheral/dual_cellulation.py +219 -0
- snappy/snap/peripheral/link.py +127 -0
- snappy/snap/peripheral/peripheral.py +159 -0
- snappy/snap/peripheral/surface.py +522 -0
- snappy/snap/peripheral/test.py +35 -0
- snappy/snap/polished_reps.py +335 -0
- snappy/snap/shapes.py +152 -0
- snappy/snap/slice_obs_HKL/__init__.py +194 -0
- snappy/snap/slice_obs_HKL/basics.py +236 -0
- snappy/snap/slice_obs_HKL/direct.py +217 -0
- snappy/snap/slice_obs_HKL/poly_norm.py +212 -0
- snappy/snap/slice_obs_HKL/rep_theory.py +424 -0
- snappy/snap/t3mlite/__init__.py +2 -0
- snappy/snap/t3mlite/arrow.py +243 -0
- snappy/snap/t3mlite/corner.py +22 -0
- snappy/snap/t3mlite/edge.py +172 -0
- snappy/snap/t3mlite/face.py +37 -0
- snappy/snap/t3mlite/files.py +211 -0
- snappy/snap/t3mlite/homology.py +53 -0
- snappy/snap/t3mlite/linalg.py +419 -0
- snappy/snap/t3mlite/mcomplex.py +1499 -0
- snappy/snap/t3mlite/perm4.py +320 -0
- snappy/snap/t3mlite/setup.py +12 -0
- snappy/snap/t3mlite/simplex.py +199 -0
- snappy/snap/t3mlite/spun.py +297 -0
- snappy/snap/t3mlite/surface.py +519 -0
- snappy/snap/t3mlite/test.py +20 -0
- snappy/snap/t3mlite/test_vs_regina.py +86 -0
- snappy/snap/t3mlite/tetrahedron.py +109 -0
- snappy/snap/t3mlite/vertex.py +42 -0
- snappy/snap/test.py +139 -0
- snappy/snap/utilities.py +288 -0
- snappy/test.py +213 -0
- snappy/test_cases.py +263 -0
- snappy/testing.py +131 -0
- snappy/tiling/__init__.py +2 -0
- snappy/tiling/dict_based_set.py +79 -0
- snappy/tiling/floor.py +49 -0
- snappy/tiling/hyperboloid_dict.py +54 -0
- snappy/tiling/iter_utils.py +78 -0
- snappy/tiling/lifted_tetrahedron.py +22 -0
- snappy/tiling/lifted_tetrahedron_set.py +54 -0
- snappy/tiling/quotient_dict.py +70 -0
- snappy/tiling/real_hash_dict.py +164 -0
- snappy/tiling/test.py +23 -0
- snappy/tiling/tile.py +224 -0
- snappy/tiling/triangle.py +33 -0
- snappy/tkterminal.py +920 -0
- snappy/twister/__init__.py +20 -0
- snappy/twister/main.py +646 -0
- snappy/twister/surfaces/S_0_1 +3 -0
- snappy/twister/surfaces/S_0_2 +3 -0
- snappy/twister/surfaces/S_0_4 +7 -0
- snappy/twister/surfaces/S_0_4_Lantern +8 -0
- snappy/twister/surfaces/S_1 +3 -0
- snappy/twister/surfaces/S_1_1 +4 -0
- snappy/twister/surfaces/S_1_2 +5 -0
- snappy/twister/surfaces/S_1_2_5 +6 -0
- snappy/twister/surfaces/S_2 +6 -0
- snappy/twister/surfaces/S_2_1 +8 -0
- snappy/twister/surfaces/S_2_heeg +10 -0
- snappy/twister/surfaces/S_3 +8 -0
- snappy/twister/surfaces/S_3_1 +10 -0
- snappy/twister/surfaces/S_4_1 +12 -0
- snappy/twister/surfaces/S_5_1 +14 -0
- snappy/twister/surfaces/heeg_fig8 +9 -0
- snappy/twister/twister_core.cpython-310-aarch64-linux-gnu.so +0 -0
- snappy/upper_halfspace/__init__.py +146 -0
- snappy/upper_halfspace/ideal_point.py +29 -0
- snappy/verify/__init__.py +13 -0
- snappy/verify/canonical.py +542 -0
- snappy/verify/complex_volume/__init__.py +18 -0
- snappy/verify/complex_volume/adjust_torsion.py +86 -0
- snappy/verify/complex_volume/closed.py +168 -0
- snappy/verify/complex_volume/compute_ptolemys.py +90 -0
- snappy/verify/complex_volume/cusped.py +56 -0
- snappy/verify/complex_volume/extended_bloch.py +201 -0
- snappy/verify/cusp_translations.py +85 -0
- snappy/verify/edge_equations.py +80 -0
- snappy/verify/exceptions.py +254 -0
- snappy/verify/hyperbolicity.py +224 -0
- snappy/verify/interval_newton_shapes_engine.py +523 -0
- snappy/verify/interval_tree.py +400 -0
- snappy/verify/krawczyk_shapes_engine.py +518 -0
- snappy/verify/real_algebra.py +286 -0
- snappy/verify/shapes.py +25 -0
- snappy/verify/square_extensions.py +1005 -0
- snappy/verify/test.py +72 -0
- snappy/verify/volume.py +128 -0
- snappy/version.py +2 -0
- snappy-3.3.dist-info/METADATA +58 -0
- snappy-3.3.dist-info/RECORD +541 -0
- snappy-3.3.dist-info/WHEEL +6 -0
- snappy-3.3.dist-info/entry_points.txt +2 -0
- snappy-3.3.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'
|