pyarchinit-photogrammetry 1.2.2__tar.gz → 1.3.1__tar.gz
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.
- {pyarchinit_photogrammetry-1.2.2/src/pyarchinit_photogrammetry.egg-info → pyarchinit_photogrammetry-1.3.1}/PKG-INFO +8 -2
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/pyproject.toml +6 -2
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/ppg_launcher.py +38 -10
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/__init__.py +4 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/_env.py +7 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/_native.py +39 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/ai/learned_net.py +117 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/ai/learned_worker.py +67 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/sam_env.py +19 -16
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/cli.py +265 -11
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/chunk.py +56 -9
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/progress.py +14 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/versions.py +3 -2
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/doctor.py +24 -2
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/chunks.py +42 -18
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/colmap_log.py +206 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/dense.py +157 -4
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/fieldcheck.py +1 -1
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/learned.py +436 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/mesh_cut.py +416 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/multispectral.py +467 -36
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/ortho.py +116 -14
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/precision.py +1 -1
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/probe.py +215 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/sfm.py +433 -54
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/texturing.py +30 -3
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/thermal.py +1596 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/__init__.py +18 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/calibration_dialog.py +3 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/dialogs.py +62 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/flow_layout.py +18 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/icons.py +3 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/image_views.py +74 -23
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/logging_setup.py +4 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/main_window.py +776 -46
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/model_view.py +31 -2
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/gui/multispectral_pane.py +413 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/panels.py +76 -2
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/pottery_dialog.py +3 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/gui/table_export.py +155 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/timeline_dialog.py +28 -5
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/translations/en.json +223 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/us_proposal_dialog.py +4 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/worker.py +117 -10
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/exports.py +30 -9
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/mesh_import.py +523 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/pdf_report.py +554 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/qgis_link.py +14 -7
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/report.py +136 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/report_content.py +1912 -0
- pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/tables.py +885 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/gcp.py +15 -8
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry.egg-info}/PKG-INFO +8 -2
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/SOURCES.txt +20 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/requires.txt +8 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_alignment_modes.py +67 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_chunks.py +1 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_cleaning.py +16 -7
- pyarchinit_photogrammetry-1.3.1/tests/test_colmap_log.py +85 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui.py +35 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_start.py +17 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_integrations.py +7 -2
- pyarchinit_photogrammetry-1.3.1/tests/test_learned.py +184 -0
- pyarchinit_photogrammetry-1.3.1/tests/test_mesh_cut.py +272 -0
- pyarchinit_photogrammetry-1.3.1/tests/test_model_import.py +295 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_multispectral.py +208 -5
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_native.py +139 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_nodes.py +4 -1
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_ortho.py +37 -0
- pyarchinit_photogrammetry-1.3.1/tests/test_packaging.py +60 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_plugins.py +13 -0
- pyarchinit_photogrammetry-1.3.1/tests/test_probe.py +96 -0
- pyarchinit_photogrammetry-1.3.1/tests/test_progress_dialog.py +81 -0
- pyarchinit_photogrammetry-1.3.1/tests/test_report.py +637 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_satellite.py +5 -2
- pyarchinit_photogrammetry-1.3.1/tests/test_thermal.py +772 -0
- pyarchinit_photogrammetry-1.2.2/src/pyarchinit_photogrammetry/gui/multispectral_pane.py +0 -195
- pyarchinit_photogrammetry-1.2.2/src/pyarchinit_photogrammetry/io/report.py +0 -92
- pyarchinit_photogrammetry-1.2.2/tests/test_packaging.py +0 -25
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/LICENSE +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/README.md +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/setup.cfg +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/__main__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/classify.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/learn.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/sam.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/sam_worker.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/app.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/measures.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/munsell.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/pottery.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/proxies.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/relief.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/sections.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/stones.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/stratigraphy.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/terrain.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/timeline.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/us_proposal.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/batch.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/bim/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/bim/ifc.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/camera.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/crs.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/document.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/geometry.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/marker.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/paradata.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/pointcloud.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/demo.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/bundle.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/cleaning.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/colour.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/confidence.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/crop.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/dem.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/dem_edit.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/diagnostics.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/elevation.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/isolate.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/masks.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/meshing.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/nodes.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/normalmap.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/overviews.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/panorama.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/patches.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/quality.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/region.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/satellite.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/tiepoints.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/tsdf.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/video.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/visibility.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/__main__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/batch_dialog.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/i18n.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/matches_dialog.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/nodes_dialog.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/plugins_dialog.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/resources/logo.svg +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/scene.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/start_page.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/theme.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/undo.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/update_dialog.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/metashape.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/photo3d.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/webodm.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/copc.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/exif.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/flythrough.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/gpkg.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/i3s.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/mesh_ply.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/qfield.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/scans.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/web.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/refine.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/targets.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/api.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/index.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/manager.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/scaffold.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/bridge.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/config.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/database.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/demo_db.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/media.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/pyarchinit5_schema.sql +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/testing/__init__.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/testing/synthetic.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/updates.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/dependency_links.txt +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/entry_points.txt +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/top_level.txt +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_archaeo.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_batch.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_bim_ai.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_bundle.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_classify.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_colour.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_dem_edit.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_dem_fill.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_dem_spikes.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_depth_mesh.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_diagnostics.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_elevation.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_env.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_exports_web.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_fieldcheck.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_fisheye_panorama.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_geometry.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_cleaning.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_layers.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_patches.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_i18n.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_i3s.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_ifc_strat.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_isolate.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_learn.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_marker_refine.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_markers.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_masks.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_measures.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_mesh_ply.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_meshing_fallback.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_munsell.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_normalmap.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_overviews.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_paradata.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_patches.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_photos.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pipeline.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pottery_demo.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pottery_search.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_precision.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_proxies.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pyarchinit.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pyarchinit_media.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_qfield.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_quality_video.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_raster_detail.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_reference_cameras.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_region.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_regressions.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_relief.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_scalebars.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_scans.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_sfm_global_check.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_stones.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_texture.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_tiepoints.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_timeline.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_tools_3d.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_undo.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_updates.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_us_proposal.py +0 -0
- {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_versions.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pyarchinit-photogrammetry
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.1
|
|
4
4
|
Summary: Open-source photogrammetry engine for archaeology and BIM, integrated with PyArchInit
|
|
5
5
|
Author-email: Enzo Cocca <enzo.ccc@gmail.com>
|
|
6
6
|
License-Expression: GPL-2.0-or-later
|
|
@@ -26,9 +26,12 @@ Requires-Dist: shapely>=2.0
|
|
|
26
26
|
Requires-Dist: trimesh>=4.0
|
|
27
27
|
Requires-Dist: contourpy>=1.1
|
|
28
28
|
Requires-Dist: ezdxf>=1.1
|
|
29
|
+
Requires-Dist: matplotlib>=3.7
|
|
29
30
|
Requires-Dist: laspy[lazrs]>=2.4
|
|
30
31
|
Requires-Dist: sqlalchemy>=2.0
|
|
31
32
|
Requires-Dist: typer>=0.9
|
|
33
|
+
Requires-Dist: fpdf2>=2.8
|
|
34
|
+
Requires-Dist: openpyxl>=3.1
|
|
32
35
|
Provides-Extra: mesh
|
|
33
36
|
Requires-Dist: open3d!=0.20.0,>=0.18; extra == "mesh"
|
|
34
37
|
Provides-Extra: bim
|
|
@@ -40,10 +43,13 @@ Provides-Extra: sam
|
|
|
40
43
|
Requires-Dist: torch>=2.3; extra == "sam"
|
|
41
44
|
Requires-Dist: sam2>=1.1; extra == "sam"
|
|
42
45
|
Requires-Dist: huggingface_hub>=0.20; extra == "sam"
|
|
46
|
+
Provides-Extra: learned
|
|
47
|
+
Requires-Dist: torch>=2.3; extra == "learned"
|
|
48
|
+
Requires-Dist: kornia>=0.8; extra == "learned"
|
|
43
49
|
Provides-Extra: learn
|
|
44
50
|
Requires-Dist: scikit-learn>=1.3; extra == "learn"
|
|
45
51
|
Provides-Extra: fast
|
|
46
|
-
Requires-Dist: pyarchinit-photogrammetry-core>=0.
|
|
52
|
+
Requires-Dist: pyarchinit-photogrammetry-core>=0.4.1; extra == "fast"
|
|
47
53
|
Provides-Extra: scans
|
|
48
54
|
Requires-Dist: pye57>=0.4; extra == "scans"
|
|
49
55
|
Provides-Extra: munsell
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "pyarchinit-photogrammetry"
|
|
7
|
-
version = "1.
|
|
7
|
+
version = "1.3.1"
|
|
8
8
|
description = "Open-source photogrammetry engine for archaeology and BIM, integrated with PyArchInit"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = "GPL-2.0-or-later"
|
|
@@ -31,9 +31,12 @@ dependencies = [
|
|
|
31
31
|
"trimesh>=4.0",
|
|
32
32
|
"contourpy>=1.1",
|
|
33
33
|
"ezdxf>=1.1",
|
|
34
|
+
"matplotlib>=3.7", # drawings (pottery, plugins' sections and logs); came only through pyvista before
|
|
34
35
|
"laspy[lazrs]>=2.4",
|
|
35
36
|
"sqlalchemy>=2.0",
|
|
36
37
|
"typer>=0.9",
|
|
38
|
+
"fpdf2>=2.8", # the processing report as PDF (io.pdf_report)
|
|
39
|
+
"openpyxl>=3.1", # the tables as Excel workbooks (io.tables)
|
|
37
40
|
]
|
|
38
41
|
|
|
39
42
|
[project.optional-dependencies]
|
|
@@ -42,8 +45,9 @@ bim = ["ifcopenshell>=0.8"]
|
|
|
42
45
|
postgis = ["psycopg2-binary>=2.9; sys_platform != 'win32' or platform_machine != 'ARM64'",
|
|
43
46
|
"psycopg>=3.1; sys_platform == 'win32' and platform_machine == 'ARM64'"] # psycopg 3 over libpq on Windows ARM64
|
|
44
47
|
sam = ["torch>=2.3", "sam2>=1.1", "huggingface_hub>=0.20"] # the weights come from the Hugging Face hub
|
|
48
|
+
learned = ["torch>=2.3", "kornia>=0.8"] # learned key points + LightGlue (engine.learned), run in a worker process
|
|
45
49
|
learn = ["scikit-learn>=1.3"] # trainable point classification (ai.learn)
|
|
46
|
-
fast = ["pyarchinit-photogrammetry-core>=0.
|
|
50
|
+
fast = ["pyarchinit-photogrammetry-core>=0.4.1"] # native kernels in Rust (native/), optional
|
|
47
51
|
scans = ["pye57>=0.4"] # laser scans in E57 (io.scans; PTX needs nothing)
|
|
48
52
|
munsell = ["colour-science>=0.4.4"] # Munsell notation of the colours (archaeo.munsell)
|
|
49
53
|
gui = ["PySide6>=6.6", "pyvista>=0.43", "pyvistaqt>=0.13", "qtawesome>=1.3", "scikit-learn>=1.3",
|
|
@@ -263,6 +263,41 @@ def _persistent_matplotlib_cache() -> None:
|
|
|
263
263
|
_crash_file = None # kept open while the application runs
|
|
264
264
|
|
|
265
265
|
|
|
266
|
+
def _log_folder() -> str:
|
|
267
|
+
"""The log folder of the interface (as ``gui.logging_setup``; ``PPG_LOG_DIR`` overrides it)."""
|
|
268
|
+
folder = os.environ.get("PPG_LOG_DIR")
|
|
269
|
+
if folder:
|
|
270
|
+
return folder
|
|
271
|
+
if sys.platform == "darwin":
|
|
272
|
+
return os.path.expanduser("~/Library/Logs/pyarchinit-photogrammetry")
|
|
273
|
+
if os.name == "nt":
|
|
274
|
+
return os.path.join(os.environ.get("LOCALAPPDATA") or os.path.expanduser("~/AppData/Local"),
|
|
275
|
+
"pyarchinit-photogrammetry", "logs")
|
|
276
|
+
return os.path.join(os.environ.get("XDG_STATE_HOME") or os.path.expanduser("~/.local/state"),
|
|
277
|
+
"pyarchinit-photogrammetry", "logs")
|
|
278
|
+
|
|
279
|
+
|
|
280
|
+
_hang_file = None
|
|
281
|
+
|
|
282
|
+
|
|
283
|
+
def check_watchdog() -> bool:
|
|
284
|
+
"""The smoke test of a build (``--check``) that stalls says where: after ``PPG_CHECK_TIMEOUT``
|
|
285
|
+
seconds (420 by default, less than the build script waits) the traceback of every thread goes
|
|
286
|
+
to ``check-hang.txt`` in the log folder and the process ends. True when it is armed."""
|
|
287
|
+
global _hang_file
|
|
288
|
+
import faulthandler
|
|
289
|
+
|
|
290
|
+
try:
|
|
291
|
+
seconds = float(os.environ.get("PPG_CHECK_TIMEOUT", "420"))
|
|
292
|
+
folder = _log_folder()
|
|
293
|
+
os.makedirs(folder, exist_ok=True)
|
|
294
|
+
_hang_file = open(os.path.join(folder, "check-hang.txt"), "w", encoding="utf-8")
|
|
295
|
+
faulthandler.dump_traceback_later(seconds, exit=True, file=_hang_file)
|
|
296
|
+
return True
|
|
297
|
+
except (OSError, ValueError):
|
|
298
|
+
return False
|
|
299
|
+
|
|
300
|
+
|
|
266
301
|
def crash_log() -> bool:
|
|
267
302
|
"""Native crashes (segfault, abort) written to ``crash.log`` in the log folder of the
|
|
268
303
|
interface (as ``gui.logging_setup``, ``PPG_LOG_DIR`` overrides it) from the very start,
|
|
@@ -274,16 +309,7 @@ def crash_log() -> bool:
|
|
|
274
309
|
|
|
275
310
|
if faulthandler.is_enabled():
|
|
276
311
|
return True
|
|
277
|
-
folder =
|
|
278
|
-
if not folder:
|
|
279
|
-
if sys.platform == "darwin":
|
|
280
|
-
folder = os.path.expanduser("~/Library/Logs/pyarchinit-photogrammetry")
|
|
281
|
-
elif os.name == "nt":
|
|
282
|
-
folder = os.path.join(os.environ.get("LOCALAPPDATA") or os.path.expanduser("~/AppData/Local"),
|
|
283
|
-
"pyarchinit-photogrammetry", "logs")
|
|
284
|
-
else:
|
|
285
|
-
folder = os.path.join(os.environ.get("XDG_STATE_HOME") or os.path.expanduser("~/.local/state"),
|
|
286
|
-
"pyarchinit-photogrammetry", "logs")
|
|
312
|
+
folder = _log_folder()
|
|
287
313
|
try:
|
|
288
314
|
os.makedirs(folder, exist_ok=True)
|
|
289
315
|
_crash_file = open(os.path.join(folder, "crash.log"), "a", encoding="utf-8")
|
|
@@ -306,6 +332,8 @@ def main(argv: list[str] | None = None) -> int:
|
|
|
306
332
|
|
|
307
333
|
return gui_main(argv)
|
|
308
334
|
crash_log()
|
|
335
|
+
if "--check" in argv:
|
|
336
|
+
check_watchdog()
|
|
309
337
|
os.environ.setdefault("QT_API", "pyside6") # qtpy (pyvistaqt) must not pick another binding
|
|
310
338
|
os.environ.setdefault("GLOG_minloglevel", "2")
|
|
311
339
|
try:
|
|
@@ -19,9 +19,12 @@ Quick start::
|
|
|
19
19
|
chunk.build_orthomosaic()
|
|
20
20
|
doc.save("scavo.ppg")
|
|
21
21
|
"""
|
|
22
|
+
from ._env import glog_flushes_each_line as _glog_flushes_each_line
|
|
22
23
|
from ._env import load_open3d_first as _load_open3d_first
|
|
23
24
|
from ._env import use_bundled_proj_data as _use_bundled_proj_data
|
|
24
25
|
|
|
26
|
+
_glog_flushes_each_line() # before pycolmap loads: its log is tailed for the progress (see _env.py)
|
|
27
|
+
|
|
25
28
|
_load_open3d_first() # Open3D's OpenMP runtime must be bound before rasterio/scipy (see _env.py)
|
|
26
29
|
|
|
27
30
|
_use_bundled_proj_data() # before anything opens a CRS (see _env.py)
|
|
@@ -32,7 +35,7 @@ from .core import (ARCHAEO_CLASSES, ASPRS_CLASSES, Camera, Chunk, Document, Mark
|
|
|
32
35
|
from .core.progress import Cancelled, Progress, print_progress
|
|
33
36
|
from . import demo # noqa: E402 (ppg.demo.create_demo)
|
|
34
37
|
|
|
35
|
-
__version__ = "1.
|
|
38
|
+
__version__ = "1.3.1"
|
|
36
39
|
|
|
37
40
|
__all__ = ["app", "Document", "Chunk", "Camera", "Sensor", "Marker", "Projection", "Reference", "ScaleBar",
|
|
38
41
|
"PointCloud", "ASPRS_CLASSES", "ARCHAEO_CLASSES", "Progress", "Cancelled", "print_progress", "__version__"]
|
|
@@ -82,3 +82,10 @@ def skip_open3d_extras() -> None:
|
|
|
82
82
|
|
|
83
83
|
plotly.draw_plotly = plotly.draw_plotly_server = unavailable
|
|
84
84
|
sys.modules[plotly.__name__] = plotly
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def glog_flushes_each_line() -> None:
|
|
88
|
+
"""COLMAP's log (glog) written to a file line by line: by default glog keeps 30 seconds of
|
|
89
|
+
lines in a buffer, and :mod:`engine.colmap_log` tails that file to show the progress of a
|
|
90
|
+
step while COLMAP runs it. Read when the library loads: call before importing pycolmap."""
|
|
91
|
+
os.environ.setdefault("GLOG_logbufsecs", "0")
|
|
@@ -116,3 +116,42 @@ def gpu_forget() -> None:
|
|
|
116
116
|
fn = getattr(core, "gpu_forget", None) if core is not None else None
|
|
117
117
|
if fn is not None:
|
|
118
118
|
fn()
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
def gpu_fuse(reference, neighbours, min_pixels: int = 3, max_reproj: float = 2.0, max_depth_rel: float = 0.01,
|
|
122
|
+
max_normal_deg: float = 20.0, support_tol: float = 0.01, device: int = -1):
|
|
123
|
+
"""The dense points of one depth map fused with its covisible maps on the GPU (API 7): every
|
|
124
|
+
map ``(key, depth (h x w float32) or None when the GPU holds it, (fx, fy, cx, cy), rotation
|
|
125
|
+
3x3, translation, order)``; returns ``(xyz, normals, pixel, pixels, support)``."""
|
|
126
|
+
fn = kernel("gpu_fuse")
|
|
127
|
+
if fn is None:
|
|
128
|
+
raise RuntimeError("the GPU fusion needs pyarchinit-photogrammetry-core 0.4 (API 7)")
|
|
129
|
+
return fn(reference, neighbours, int(min_pixels), float(max_reproj), float(max_depth_rel), float(max_normal_deg),
|
|
130
|
+
float(support_tol), int(device))
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
def gpu_fuse_cached(device: int = -1) -> list[int]:
|
|
134
|
+
"""The keys of the depth maps the GPU keeps for the fusion."""
|
|
135
|
+
fn = kernel("gpu_fuse_cached")
|
|
136
|
+
return list(fn(int(device))) if fn is not None else []
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
def gpu_fuse_forget(device: int = -1) -> None:
|
|
140
|
+
"""Drop the depth maps the GPU keeps for the fusion: their keys are image ids, unique within
|
|
141
|
+
one workspace only."""
|
|
142
|
+
fn = kernel("gpu_fuse_forget")
|
|
143
|
+
if fn is not None:
|
|
144
|
+
fn(int(device))
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
def gpu_sift(image, max_features: int = 8192, first_octave: int = -1, num_octaves: int = 4, octave_resolution: int = 3,
|
|
148
|
+
peak_threshold: float = 0.02 / 3.0, edge_threshold: float = 10.0, max_orientations: int = 2,
|
|
149
|
+
upright: bool = False, device: int = -1):
|
|
150
|
+
"""SIFT key points ``(n, 4)`` float32 (x, y, scale, orientation; the centre of the first pixel
|
|
151
|
+
at (0, 0), as VLFeat) and descriptors ``(n, 128)`` uint8 of a grey float image in [0, 1] on
|
|
152
|
+
the GPU, as COLMAP's CPU extractor computes them (API 6 of the extension)."""
|
|
153
|
+
fn = kernel("gpu_sift")
|
|
154
|
+
if fn is None:
|
|
155
|
+
raise RuntimeError("the GPU SIFT needs pyarchinit-photogrammetry-core 0.4 (API 6)")
|
|
156
|
+
return fn(image, int(max_features), int(first_octave), int(num_octaves), int(octave_resolution),
|
|
157
|
+
float(peak_threshold), float(edge_threshold), int(max_orientations), bool(upright), int(device))
|
|
@@ -0,0 +1,117 @@
|
|
|
1
|
+
"""Learned key points and LightGlue with kornia: the part that needs PyTorch, on its own.
|
|
2
|
+
|
|
3
|
+
The program imports it through :mod:`pyarchinit_photogrammetry.engine.learned` when PyTorch and
|
|
4
|
+
kornia are installed beside it. The packaged application has no PyTorch: there it runs in the
|
|
5
|
+
separate environment of SAM 2.1 through ``learned_worker.py``. So it imports nothing but numpy,
|
|
6
|
+
torch and kornia.
|
|
7
|
+
|
|
8
|
+
ALIKED (Zhao et al. 2023, BSD-3-Clause) or DISK (Tyszkiewicz et al. 2020, Apache-2.0) find the key points and
|
|
9
|
+
describe them with a small network; LightGlue (Lindenberger et al. 2023, Apache-2.0) matches two
|
|
10
|
+
sets of them with attention and leaves out the pairs it is not sure of. The key points come back
|
|
11
|
+
with the centre of the first pixel at 0, as OpenCV.
|
|
12
|
+
"""
|
|
13
|
+
from __future__ import annotations
|
|
14
|
+
|
|
15
|
+
from collections import OrderedDict
|
|
16
|
+
|
|
17
|
+
import numpy as np
|
|
18
|
+
|
|
19
|
+
KINDS = {"disk": "DISK + LightGlue", "aliked": "ALIKED + LightGlue"}
|
|
20
|
+
MAX_KEYPOINTS = 4096
|
|
21
|
+
CACHED_FILES = 96 # descriptor files kept in memory while the pairs are matched
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def pick_device(name: str | None = None):
|
|
25
|
+
"""CUDA, else Apple's GPU (Metal), else the CPU; ``name`` forces one."""
|
|
26
|
+
import torch
|
|
27
|
+
|
|
28
|
+
if name:
|
|
29
|
+
return torch.device(name)
|
|
30
|
+
if torch.cuda.is_available():
|
|
31
|
+
return torch.device("cuda")
|
|
32
|
+
mps = getattr(torch.backends, "mps", None)
|
|
33
|
+
if mps is not None and mps.is_available():
|
|
34
|
+
return torch.device("mps")
|
|
35
|
+
return torch.device("cpu")
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
class Features:
|
|
39
|
+
"""The extractor of one kind and LightGlue for it, on the device."""
|
|
40
|
+
|
|
41
|
+
def __init__(self, kind: str = "disk", max_keypoints: int = MAX_KEYPOINTS, device: str | None = None):
|
|
42
|
+
import kornia.feature as KF
|
|
43
|
+
import torch
|
|
44
|
+
|
|
45
|
+
if kind not in KINDS:
|
|
46
|
+
raise ValueError(f"unknown learned features {kind!r}: {', '.join(KINDS)}")
|
|
47
|
+
self.kind = kind
|
|
48
|
+
self.max_keypoints = int(max_keypoints)
|
|
49
|
+
self.dev = pick_device(device)
|
|
50
|
+
self._torch = torch
|
|
51
|
+
self._KF = KF
|
|
52
|
+
if kind == "aliked":
|
|
53
|
+
# threshold 0: the strongest points up to the limit, whatever their score (thermal frames have weak ones)
|
|
54
|
+
self.net = KF.ALIKED.from_pretrained("aliked-n16", max_num_keypoints=self.max_keypoints,
|
|
55
|
+
detection_threshold=0.0, device=self.dev).eval()
|
|
56
|
+
else:
|
|
57
|
+
self.net = KF.DISK.from_pretrained("depth", device=self.dev).eval()
|
|
58
|
+
self.matcher = KF.LightGlueMatcher(kind).to(self.dev).eval()
|
|
59
|
+
self._files: OrderedDict[str, tuple] = OrderedDict()
|
|
60
|
+
|
|
61
|
+
@property
|
|
62
|
+
def device(self) -> str:
|
|
63
|
+
return self.dev.type
|
|
64
|
+
|
|
65
|
+
def extract(self, grey: np.ndarray) -> tuple[np.ndarray, np.ndarray]:
|
|
66
|
+
"""Key points ``(N, 2)`` float32 (x, y) and descriptors ``(N, D)`` float16 of a grey image
|
|
67
|
+
(uint8, or float in 0..1)."""
|
|
68
|
+
torch = self._torch
|
|
69
|
+
img = np.asarray(grey)
|
|
70
|
+
scale = 255.0 if img.dtype == np.uint8 else 1.0
|
|
71
|
+
t = torch.from_numpy(np.ascontiguousarray(img, np.float32) / scale)[None, None].repeat(1, 3, 1, 1).to(self.dev)
|
|
72
|
+
with torch.inference_mode():
|
|
73
|
+
if self.kind == "disk":
|
|
74
|
+
out = self.net(t, n=self.max_keypoints, pad_if_not_divisible=True)
|
|
75
|
+
else:
|
|
76
|
+
out = self.net(t)
|
|
77
|
+
kp = out[0].keypoints.float().cpu().numpy().astype(np.float32)
|
|
78
|
+
desc = out[0].descriptors.float().cpu().numpy().astype(np.float16)
|
|
79
|
+
h, w = img.shape[:2]
|
|
80
|
+
inside = (kp[:, 0] <= w - 1) & (kp[:, 1] <= h - 1) # DISK pads to a multiple of 16
|
|
81
|
+
return np.ascontiguousarray(kp[inside]), np.ascontiguousarray(desc[inside])
|
|
82
|
+
|
|
83
|
+
def match(self, kp1, desc1, size1, kp2, desc2, size2) -> np.ndarray:
|
|
84
|
+
"""LightGlue's matches ``(M, 2)`` uint32 (indices into the two sets); ``size`` = (height, width)
|
|
85
|
+
of the image the points were found on."""
|
|
86
|
+
torch, KF = self._torch, self._KF
|
|
87
|
+
if len(kp1) < 2 or len(kp2) < 2:
|
|
88
|
+
return np.zeros((0, 2), np.uint32)
|
|
89
|
+
dev = self.dev
|
|
90
|
+
k1 = torch.from_numpy(np.ascontiguousarray(kp1, np.float32)).to(dev)
|
|
91
|
+
k2 = torch.from_numpy(np.ascontiguousarray(kp2, np.float32)).to(dev)
|
|
92
|
+
d1 = torch.from_numpy(np.ascontiguousarray(desc1, np.float32)).to(dev)
|
|
93
|
+
d2 = torch.from_numpy(np.ascontiguousarray(desc2, np.float32)).to(dev)
|
|
94
|
+
with torch.inference_mode():
|
|
95
|
+
laf1 = KF.laf_from_center_scale_ori(k1[None], torch.ones(1, len(k1), 1, 1, device=dev))
|
|
96
|
+
laf2 = KF.laf_from_center_scale_ori(k2[None], torch.ones(1, len(k2), 1, 1, device=dev))
|
|
97
|
+
_dist, idx = self.matcher(d1, d2, laf1, laf2, hw1=tuple(int(v) for v in size1),
|
|
98
|
+
hw2=tuple(int(v) for v in size2))
|
|
99
|
+
return np.ascontiguousarray(idx.cpu().numpy().astype(np.uint32).reshape(-1, 2))
|
|
100
|
+
|
|
101
|
+
def _load(self, path: str) -> tuple:
|
|
102
|
+
got = self._files.get(path)
|
|
103
|
+
if got is None:
|
|
104
|
+
with np.load(path) as z:
|
|
105
|
+
got = (z["kp"], z["desc"], tuple(int(v) for v in z["size"]))
|
|
106
|
+
self._files[path] = got
|
|
107
|
+
if len(self._files) > CACHED_FILES:
|
|
108
|
+
self._files.popitem(last=False)
|
|
109
|
+
else:
|
|
110
|
+
self._files.move_to_end(path)
|
|
111
|
+
return got
|
|
112
|
+
|
|
113
|
+
def match_files(self, a: str, b: str) -> np.ndarray:
|
|
114
|
+
""":meth:`match` on two files written by the extraction (``kp``, ``desc``, ``size``)."""
|
|
115
|
+
ka, da, sa = self._load(str(a))
|
|
116
|
+
kb, db, sb = self._load(str(b))
|
|
117
|
+
return self.match(ka, da, sa, kb, db, sb)
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"""Worker process of the learned key points (ALIKED or DISK) and LightGlue.
|
|
2
|
+
|
|
3
|
+
Run by the separate Python environment of the packaged application (the one of SAM 2.1, with
|
|
4
|
+
PyTorch and kornia), so it imports nothing from pyarchinit_photogrammetry, only
|
|
5
|
+
``learned_net.py`` beside it. Same protocol as ``sam_worker.py``: on stdin/stdout each message is
|
|
6
|
+
an 8-byte big-endian length followed by a pickle. Requests are dicts with ``op``:
|
|
7
|
+
|
|
8
|
+
* ``init`` ``{"kind", "max_keypoints", "device"?}`` -> ``{"device"}``
|
|
9
|
+
* ``extract`` ``{"image"}`` (grey uint8) -> ``{"kp", "desc"}``
|
|
10
|
+
* ``match`` ``{"a", "b"}`` (descriptor files) -> ``{"matches"}``
|
|
11
|
+
* ``quit``
|
|
12
|
+
|
|
13
|
+
Replies are ``{"ok": True, ...}`` or ``{"ok": False, "error": traceback}``.
|
|
14
|
+
"""
|
|
15
|
+
from __future__ import annotations
|
|
16
|
+
|
|
17
|
+
import os
|
|
18
|
+
import pickle
|
|
19
|
+
import struct
|
|
20
|
+
import sys
|
|
21
|
+
import traceback
|
|
22
|
+
|
|
23
|
+
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _read(stream):
|
|
27
|
+
head = stream.read(8)
|
|
28
|
+
if len(head) < 8:
|
|
29
|
+
return None
|
|
30
|
+
(n,) = struct.unpack(">Q", head)
|
|
31
|
+
return pickle.loads(stream.read(n))
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
def _write(stream, obj) -> None:
|
|
35
|
+
data = pickle.dumps(obj, protocol=4)
|
|
36
|
+
stream.write(struct.pack(">Q", len(data)) + data)
|
|
37
|
+
stream.flush()
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def main() -> None:
|
|
41
|
+
stdin, stdout = sys.stdin.buffer, sys.stdout.buffer
|
|
42
|
+
sys.stdout = sys.stderr # anything the libraries print must not break the protocol
|
|
43
|
+
feats = None
|
|
44
|
+
while True:
|
|
45
|
+
req = _read(stdin)
|
|
46
|
+
if req is None or req.get("op") == "quit":
|
|
47
|
+
break
|
|
48
|
+
try:
|
|
49
|
+
op = req["op"]
|
|
50
|
+
if op == "init":
|
|
51
|
+
from learned_net import Features
|
|
52
|
+
|
|
53
|
+
feats = Features(req.get("kind", "disk"), int(req.get("max_keypoints", 4096)), req.get("device"))
|
|
54
|
+
_write(stdout, {"ok": True, "device": feats.device})
|
|
55
|
+
elif op == "extract":
|
|
56
|
+
kp, desc = feats.extract(req["image"])
|
|
57
|
+
_write(stdout, {"ok": True, "kp": kp, "desc": desc})
|
|
58
|
+
elif op == "match":
|
|
59
|
+
_write(stdout, {"ok": True, "matches": feats.match_files(req["a"], req["b"])})
|
|
60
|
+
else:
|
|
61
|
+
_write(stdout, {"ok": False, "error": f"unknown op {op!r}"})
|
|
62
|
+
except Exception: # noqa: BLE001 - every error goes back to the program
|
|
63
|
+
_write(stdout, {"ok": False, "error": traceback.format_exc()})
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
main()
|
|
@@ -9,9 +9,14 @@ its official GitHub release when it is not on the system):
|
|
|
9
9
|
The model runs in a worker process of that environment (``sam_worker.py``) and
|
|
10
10
|
:class:`ExternalSam2Segmenter` talks to it; it has the same methods as
|
|
11
11
|
:class:`~pyarchinit_photogrammetry.ai.sam.Sam2Segmenter`, so everything else is unchanged.
|
|
12
|
+
|
|
13
|
+
When PyTorch and sam2 are installed beside the program (the ``[sam]`` extra) the same worker runs
|
|
14
|
+
with this Python: never PyTorch in the program's process, where pycolmap is loaded. Each brings
|
|
15
|
+
its own OpenMP runtime, and the second to start aborts the process (``OMP: Error #15``).
|
|
12
16
|
"""
|
|
13
17
|
from __future__ import annotations
|
|
14
18
|
|
|
19
|
+
import importlib.util
|
|
15
20
|
import io
|
|
16
21
|
import json
|
|
17
22
|
import os
|
|
@@ -28,7 +33,7 @@ from pathlib import Path
|
|
|
28
33
|
|
|
29
34
|
import numpy as np
|
|
30
35
|
|
|
31
|
-
PACKAGES = ["torch", "sam2", "huggingface_hub", "numpy", "pillow"]
|
|
36
|
+
PACKAGES = ["torch", "sam2", "huggingface_hub", "numpy", "pillow", "kornia"] # kornia: learned key points (engine.learned)
|
|
32
37
|
UV_URL = "https://github.com/astral-sh/uv/releases/latest/download/uv-{target}.{ext}"
|
|
33
38
|
|
|
34
39
|
|
|
@@ -57,22 +62,21 @@ def is_installed(env: Path | None = None) -> bool:
|
|
|
57
62
|
|
|
58
63
|
|
|
59
64
|
def in_process_available() -> bool:
|
|
60
|
-
"""PyTorch and sam2
|
|
61
|
-
|
|
65
|
+
"""PyTorch and sam2 installed for this Python (pip installs with the [sam] extra), with
|
|
66
|
+
huggingface_hub that downloads the weights (sam2 does not require it). Looked up, not
|
|
67
|
+
imported: importing PyTorch here would start its OpenMP runtime beside pycolmap's."""
|
|
68
|
+
if getattr(sys, "frozen", False): # the packaged application: its executable is not a Python
|
|
69
|
+
return False
|
|
62
70
|
try:
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
import torch # noqa: F401
|
|
66
|
-
|
|
67
|
-
return True
|
|
68
|
-
except Exception:
|
|
71
|
+
return all(importlib.util.find_spec(name) is not None for name in ("torch", "sam2", "huggingface_hub"))
|
|
72
|
+
except (ImportError, ValueError):
|
|
69
73
|
return False
|
|
70
74
|
|
|
71
75
|
|
|
72
76
|
def available() -> str | None:
|
|
73
|
-
"""``"
|
|
77
|
+
"""``"local"`` (the worker runs with this Python), ``"external"`` or None."""
|
|
74
78
|
if in_process_available():
|
|
75
|
-
return "
|
|
79
|
+
return "local"
|
|
76
80
|
if is_installed():
|
|
77
81
|
return "external"
|
|
78
82
|
return None
|
|
@@ -272,12 +276,11 @@ class ExternalSam2Segmenter:
|
|
|
272
276
|
|
|
273
277
|
|
|
274
278
|
def make_segmenter(model: str = "small"):
|
|
275
|
-
"""The SAM 2.1 segmenter available here
|
|
279
|
+
"""The SAM 2.1 segmenter available here, always in a worker process (see the module): with
|
|
280
|
+
this Python, with the external environment, or ImportError."""
|
|
276
281
|
mode = available()
|
|
277
|
-
if mode == "
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
return Sam2Segmenter(model)
|
|
282
|
+
if mode == "local":
|
|
283
|
+
return ExternalSam2Segmenter(model, python=sys.executable)
|
|
281
284
|
if mode == "external":
|
|
282
285
|
return ExternalSam2Segmenter(model)
|
|
283
286
|
raise ImportError("SAM 2.1 non e' installato")
|