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.
Files changed (248) hide show
  1. {pyarchinit_photogrammetry-1.2.2/src/pyarchinit_photogrammetry.egg-info → pyarchinit_photogrammetry-1.3.1}/PKG-INFO +8 -2
  2. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/pyproject.toml +6 -2
  3. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/ppg_launcher.py +38 -10
  4. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/__init__.py +4 -1
  5. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/_env.py +7 -0
  6. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/_native.py +39 -0
  7. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/ai/learned_net.py +117 -0
  8. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/ai/learned_worker.py +67 -0
  9. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/sam_env.py +19 -16
  10. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/cli.py +265 -11
  11. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/chunk.py +56 -9
  12. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/progress.py +14 -1
  13. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/versions.py +3 -2
  14. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/doctor.py +24 -2
  15. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/chunks.py +42 -18
  16. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/colmap_log.py +206 -0
  17. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/dense.py +157 -4
  18. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/fieldcheck.py +1 -1
  19. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/learned.py +436 -0
  20. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/mesh_cut.py +416 -0
  21. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/multispectral.py +467 -36
  22. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/ortho.py +116 -14
  23. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/precision.py +1 -1
  24. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/probe.py +215 -0
  25. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/sfm.py +433 -54
  26. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/texturing.py +30 -3
  27. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/engine/thermal.py +1596 -0
  28. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/__init__.py +18 -0
  29. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/calibration_dialog.py +3 -0
  30. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/dialogs.py +62 -1
  31. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/flow_layout.py +18 -1
  32. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/icons.py +3 -1
  33. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/image_views.py +74 -23
  34. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/logging_setup.py +4 -0
  35. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/main_window.py +776 -46
  36. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/model_view.py +31 -2
  37. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/gui/multispectral_pane.py +413 -0
  38. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/panels.py +76 -2
  39. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/pottery_dialog.py +3 -0
  40. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/gui/table_export.py +155 -0
  41. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/timeline_dialog.py +28 -5
  42. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/translations/en.json +223 -1
  43. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/us_proposal_dialog.py +4 -0
  44. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/worker.py +117 -10
  45. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/exports.py +30 -9
  46. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/mesh_import.py +523 -0
  47. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/pdf_report.py +554 -0
  48. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/qgis_link.py +14 -7
  49. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/report.py +136 -0
  50. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/report_content.py +1912 -0
  51. pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry/io/tables.py +885 -0
  52. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/gcp.py +15 -8
  53. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1/src/pyarchinit_photogrammetry.egg-info}/PKG-INFO +8 -2
  54. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/SOURCES.txt +20 -0
  55. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/requires.txt +8 -1
  56. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_alignment_modes.py +67 -0
  57. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_chunks.py +1 -1
  58. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_cleaning.py +16 -7
  59. pyarchinit_photogrammetry-1.3.1/tests/test_colmap_log.py +85 -0
  60. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui.py +35 -0
  61. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_start.py +17 -0
  62. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_integrations.py +7 -2
  63. pyarchinit_photogrammetry-1.3.1/tests/test_learned.py +184 -0
  64. pyarchinit_photogrammetry-1.3.1/tests/test_mesh_cut.py +272 -0
  65. pyarchinit_photogrammetry-1.3.1/tests/test_model_import.py +295 -0
  66. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_multispectral.py +208 -5
  67. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_native.py +139 -0
  68. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_nodes.py +4 -1
  69. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_ortho.py +37 -0
  70. pyarchinit_photogrammetry-1.3.1/tests/test_packaging.py +60 -0
  71. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_plugins.py +13 -0
  72. pyarchinit_photogrammetry-1.3.1/tests/test_probe.py +96 -0
  73. pyarchinit_photogrammetry-1.3.1/tests/test_progress_dialog.py +81 -0
  74. pyarchinit_photogrammetry-1.3.1/tests/test_report.py +637 -0
  75. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_satellite.py +5 -2
  76. pyarchinit_photogrammetry-1.3.1/tests/test_thermal.py +772 -0
  77. pyarchinit_photogrammetry-1.2.2/src/pyarchinit_photogrammetry/gui/multispectral_pane.py +0 -195
  78. pyarchinit_photogrammetry-1.2.2/src/pyarchinit_photogrammetry/io/report.py +0 -92
  79. pyarchinit_photogrammetry-1.2.2/tests/test_packaging.py +0 -25
  80. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/LICENSE +0 -0
  81. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/README.md +0 -0
  82. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/setup.cfg +0 -0
  83. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/__main__.py +0 -0
  84. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/__init__.py +0 -0
  85. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/classify.py +0 -0
  86. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/learn.py +0 -0
  87. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/sam.py +0 -0
  88. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/ai/sam_worker.py +0 -0
  89. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/app.py +0 -0
  90. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/__init__.py +0 -0
  91. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/measures.py +0 -0
  92. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/munsell.py +0 -0
  93. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/pottery.py +0 -0
  94. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/proxies.py +0 -0
  95. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/relief.py +0 -0
  96. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/sections.py +0 -0
  97. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/stones.py +0 -0
  98. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/stratigraphy.py +0 -0
  99. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/terrain.py +0 -0
  100. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/timeline.py +0 -0
  101. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/archaeo/us_proposal.py +0 -0
  102. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/batch.py +0 -0
  103. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/bim/__init__.py +0 -0
  104. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/bim/ifc.py +0 -0
  105. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/__init__.py +0 -0
  106. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/camera.py +0 -0
  107. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/crs.py +0 -0
  108. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/document.py +0 -0
  109. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/geometry.py +0 -0
  110. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/marker.py +0 -0
  111. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/paradata.py +0 -0
  112. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/core/pointcloud.py +0 -0
  113. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/demo.py +0 -0
  114. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/__init__.py +0 -0
  115. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/bundle.py +0 -0
  116. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/cleaning.py +0 -0
  117. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/colour.py +0 -0
  118. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/confidence.py +0 -0
  119. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/crop.py +0 -0
  120. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/dem.py +0 -0
  121. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/dem_edit.py +0 -0
  122. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/diagnostics.py +0 -0
  123. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/elevation.py +0 -0
  124. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/isolate.py +0 -0
  125. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/masks.py +0 -0
  126. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/meshing.py +0 -0
  127. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/nodes.py +0 -0
  128. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/normalmap.py +0 -0
  129. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/overviews.py +0 -0
  130. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/panorama.py +0 -0
  131. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/patches.py +0 -0
  132. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/quality.py +0 -0
  133. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/region.py +0 -0
  134. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/satellite.py +0 -0
  135. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/tiepoints.py +0 -0
  136. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/tsdf.py +0 -0
  137. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/video.py +0 -0
  138. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/engine/visibility.py +0 -0
  139. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/__main__.py +0 -0
  140. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/batch_dialog.py +0 -0
  141. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/i18n.py +0 -0
  142. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/matches_dialog.py +0 -0
  143. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/nodes_dialog.py +0 -0
  144. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/plugins_dialog.py +0 -0
  145. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/resources/logo.svg +0 -0
  146. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/scene.py +0 -0
  147. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/start_page.py +0 -0
  148. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/theme.py +0 -0
  149. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/undo.py +0 -0
  150. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/gui/update_dialog.py +0 -0
  151. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/__init__.py +0 -0
  152. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/metashape.py +0 -0
  153. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/photo3d.py +0 -0
  154. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/integrations/webodm.py +0 -0
  155. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/__init__.py +0 -0
  156. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/copc.py +0 -0
  157. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/exif.py +0 -0
  158. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/flythrough.py +0 -0
  159. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/gpkg.py +0 -0
  160. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/i3s.py +0 -0
  161. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/mesh_ply.py +0 -0
  162. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/qfield.py +0 -0
  163. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/scans.py +0 -0
  164. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/io/web.py +0 -0
  165. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/__init__.py +0 -0
  166. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/refine.py +0 -0
  167. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/markers/targets.py +0 -0
  168. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/__init__.py +0 -0
  169. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/api.py +0 -0
  170. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/index.py +0 -0
  171. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/manager.py +0 -0
  172. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/plugins/scaffold.py +0 -0
  173. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/__init__.py +0 -0
  174. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/bridge.py +0 -0
  175. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/config.py +0 -0
  176. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/database.py +0 -0
  177. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/demo_db.py +0 -0
  178. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/media.py +0 -0
  179. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/pyarchinit/pyarchinit5_schema.sql +0 -0
  180. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/testing/__init__.py +0 -0
  181. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/testing/synthetic.py +0 -0
  182. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry/updates.py +0 -0
  183. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/dependency_links.txt +0 -0
  184. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/entry_points.txt +0 -0
  185. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/src/pyarchinit_photogrammetry.egg-info/top_level.txt +0 -0
  186. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_archaeo.py +0 -0
  187. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_batch.py +0 -0
  188. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_bim_ai.py +0 -0
  189. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_bundle.py +0 -0
  190. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_classify.py +0 -0
  191. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_colour.py +0 -0
  192. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_dem_edit.py +0 -0
  193. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_dem_fill.py +0 -0
  194. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_dem_spikes.py +0 -0
  195. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_depth_mesh.py +0 -0
  196. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_diagnostics.py +0 -0
  197. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_elevation.py +0 -0
  198. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_env.py +0 -0
  199. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_exports_web.py +0 -0
  200. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_fieldcheck.py +0 -0
  201. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_fisheye_panorama.py +0 -0
  202. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_geometry.py +0 -0
  203. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_cleaning.py +0 -0
  204. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_layers.py +0 -0
  205. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_gui_patches.py +0 -0
  206. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_i18n.py +0 -0
  207. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_i3s.py +0 -0
  208. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_ifc_strat.py +0 -0
  209. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_isolate.py +0 -0
  210. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_learn.py +0 -0
  211. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_marker_refine.py +0 -0
  212. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_markers.py +0 -0
  213. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_masks.py +0 -0
  214. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_measures.py +0 -0
  215. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_mesh_ply.py +0 -0
  216. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_meshing_fallback.py +0 -0
  217. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_munsell.py +0 -0
  218. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_normalmap.py +0 -0
  219. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_overviews.py +0 -0
  220. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_paradata.py +0 -0
  221. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_patches.py +0 -0
  222. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_photos.py +0 -0
  223. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pipeline.py +0 -0
  224. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pottery_demo.py +0 -0
  225. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pottery_search.py +0 -0
  226. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_precision.py +0 -0
  227. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_proxies.py +0 -0
  228. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pyarchinit.py +0 -0
  229. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_pyarchinit_media.py +0 -0
  230. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_qfield.py +0 -0
  231. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_quality_video.py +0 -0
  232. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_raster_detail.py +0 -0
  233. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_reference_cameras.py +0 -0
  234. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_region.py +0 -0
  235. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_regressions.py +0 -0
  236. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_relief.py +0 -0
  237. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_scalebars.py +0 -0
  238. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_scans.py +0 -0
  239. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_sfm_global_check.py +0 -0
  240. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_stones.py +0 -0
  241. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_texture.py +0 -0
  242. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_tiepoints.py +0 -0
  243. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_timeline.py +0 -0
  244. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_tools_3d.py +0 -0
  245. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_undo.py +0 -0
  246. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_updates.py +0 -0
  247. {pyarchinit_photogrammetry-1.2.2 → pyarchinit_photogrammetry-1.3.1}/tests/test_us_proposal.py +0 -0
  248. {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.2.2
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.3; extra == "fast"
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.2.2"
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.3"] # native kernels in Rust (native/), optional
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 = os.environ.get("PPG_LOG_DIR")
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.2.2"
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 importable in this interpreter (pip installs with the [sam] extra),
61
- with huggingface_hub that downloads the weights (sam2 does not require it)."""
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
- import huggingface_hub # noqa: F401
64
- import sam2 # noqa: F401
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
- """``"inprocess"``, ``"external"`` or None."""
77
+ """``"local"`` (the worker runs with this Python), ``"external"`` or None."""
74
78
  if in_process_available():
75
- return "inprocess"
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: in process, external environment, or ImportError."""
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 == "inprocess":
278
- from .sam import Sam2Segmenter
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")