pyarchinit-photogrammetry 0.2.0__tar.gz → 0.4.0__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 (110) hide show
  1. pyarchinit_photogrammetry-0.4.0/PKG-INFO +331 -0
  2. pyarchinit_photogrammetry-0.4.0/README.md +270 -0
  3. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/pyproject.toml +11 -6
  4. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/__init__.py +9 -2
  5. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/_env.py +62 -0
  6. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/ai/sam_env.py +242 -0
  7. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/ai/sam_worker.py +149 -0
  8. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/archaeo/proxies.py +184 -0
  9. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/archaeo/terrain.py +44 -11
  10. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/bim/ifc.py +261 -0
  11. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/cli.py +56 -4
  12. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/chunk.py +26 -0
  13. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/demo.py +62 -5
  14. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/doctor.py +215 -0
  15. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/dense.py +2 -2
  16. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/engine/isolate.py +148 -0
  17. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/engine/meshing.py +237 -0
  18. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/sfm.py +70 -0
  19. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/__init__.py +142 -0
  20. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/dialogs.py +824 -0
  21. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/icons.py +122 -0
  22. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/gui/image_views.py +148 -16
  23. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/logging_setup.py +135 -0
  24. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/main_window.py +2195 -0
  25. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/gui/model_view.py +2 -2
  26. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/panels.py +1018 -0
  27. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/resources/logo.svg +33 -0
  28. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/gui/scene.py +22 -0
  29. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/start_page.py +119 -0
  30. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/gui/theme.py +132 -0
  31. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/gui/worker.py +90 -18
  32. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/integrations/metashape.py +394 -0
  33. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/integrations/photo3d.py +319 -0
  34. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/integrations/webodm.py +144 -0
  35. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/io/qgis_link.py +265 -0
  36. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/pyarchinit/bridge.py +157 -6
  37. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/pyarchinit/database.py +19 -0
  38. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/pyarchinit/demo_db.py +249 -0
  39. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/pyarchinit/media.py +4 -3
  40. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/pyarchinit/pyarchinit5_schema.sql +72 -0
  41. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/testing/__init__.py +0 -0
  42. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/testing/synthetic.py +173 -3
  43. pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry.egg-info/PKG-INFO +331 -0
  44. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry.egg-info/SOURCES.txt +25 -0
  45. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry.egg-info/requires.txt +12 -5
  46. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_archaeo.py +7 -2
  47. pyarchinit_photogrammetry-0.4.0/tests/test_env.py +39 -0
  48. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_gui.py +8 -15
  49. pyarchinit_photogrammetry-0.4.0/tests/test_gui_layers.py +172 -0
  50. pyarchinit_photogrammetry-0.4.0/tests/test_integrations.py +236 -0
  51. pyarchinit_photogrammetry-0.4.0/tests/test_isolate.py +68 -0
  52. pyarchinit_photogrammetry-0.4.0/tests/test_meshing_fallback.py +50 -0
  53. pyarchinit_photogrammetry-0.4.0/tests/test_packaging.py +25 -0
  54. pyarchinit_photogrammetry-0.4.0/tests/test_pottery_demo.py +51 -0
  55. pyarchinit_photogrammetry-0.4.0/tests/test_proxies.py +140 -0
  56. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_regressions.py +35 -3
  57. pyarchinit_photogrammetry-0.2.0/PKG-INFO +0 -232
  58. pyarchinit_photogrammetry-0.2.0/README.md +0 -177
  59. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/bim/ifc.py +0 -143
  60. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/engine/meshing.py +0 -144
  61. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/gui/__init__.py +0 -43
  62. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/gui/dialogs.py +0 -266
  63. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/gui/main_window.py +0 -1286
  64. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/gui/panels.py +0 -461
  65. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/pyarchinit/demo_db.py +0 -94
  66. pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry.egg-info/PKG-INFO +0 -232
  67. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/LICENSE +0 -0
  68. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/setup.cfg +0 -0
  69. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/__main__.py +0 -0
  70. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/ai/__init__.py +0 -0
  71. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/ai/classify.py +0 -0
  72. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/ai/sam.py +0 -0
  73. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/app.py +0 -0
  74. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/archaeo/__init__.py +0 -0
  75. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/archaeo/pottery.py +0 -0
  76. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/archaeo/sections.py +0 -0
  77. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/archaeo/stratigraphy.py +0 -0
  78. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/bim/__init__.py +0 -0
  79. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/__init__.py +0 -0
  80. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/camera.py +0 -0
  81. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/crs.py +0 -0
  82. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/document.py +0 -0
  83. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/geometry.py +0 -0
  84. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/marker.py +0 -0
  85. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/pointcloud.py +0 -0
  86. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/core/progress.py +0 -0
  87. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/__init__.py +0 -0
  88. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/dem.py +0 -0
  89. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/ortho.py +0 -0
  90. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/texturing.py +0 -0
  91. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/engine/visibility.py +0 -0
  92. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/gui/__main__.py +0 -0
  93. {pyarchinit_photogrammetry-0.2.0/src/pyarchinit_photogrammetry/testing → pyarchinit_photogrammetry-0.4.0/src/pyarchinit_photogrammetry/integrations}/__init__.py +0 -0
  94. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/io/__init__.py +0 -0
  95. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/io/exif.py +0 -0
  96. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/io/exports.py +0 -0
  97. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/io/report.py +0 -0
  98. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/markers/__init__.py +0 -0
  99. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/markers/gcp.py +0 -0
  100. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/markers/targets.py +0 -0
  101. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/pyarchinit/__init__.py +0 -0
  102. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry/pyarchinit/config.py +0 -0
  103. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry.egg-info/dependency_links.txt +0 -0
  104. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry.egg-info/entry_points.txt +0 -0
  105. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/src/pyarchinit_photogrammetry.egg-info/top_level.txt +0 -0
  106. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_bim_ai.py +0 -0
  107. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_geometry.py +0 -0
  108. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_markers.py +0 -0
  109. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_pipeline.py +0 -0
  110. {pyarchinit_photogrammetry-0.2.0 → pyarchinit_photogrammetry-0.4.0}/tests/test_pyarchinit.py +0 -0
@@ -0,0 +1,331 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyarchinit-photogrammetry
3
+ Version: 0.4.0
4
+ Summary: Open-source photogrammetry engine for archaeology and BIM, integrated with PyArchInit
5
+ Author-email: Enzo Cocca <enzo.ccc@gmail.com>
6
+ License-Expression: GPL-2.0-or-later
7
+ Project-URL: Homepage, https://github.com/enzococca/pyarchinit-photogrammetry
8
+ Project-URL: Issues, https://github.com/enzococca/pyarchinit-photogrammetry/issues
9
+ Keywords: photogrammetry,archaeology,structure-from-motion,orthophoto,DEM,PyArchInit,BIM,IFC
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Science/Research
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Scientific/Engineering :: GIS
14
+ Classifier: Topic :: Scientific/Engineering :: Image Processing
15
+ Requires-Python: >=3.10
16
+ Description-Content-Type: text/markdown
17
+ License-File: LICENSE
18
+ Requires-Dist: numpy>=1.24
19
+ Requires-Dist: scipy>=1.10
20
+ Requires-Dist: pycolmap>=3.11
21
+ Requires-Dist: opencv-contrib-python-headless>=4.8
22
+ Requires-Dist: pillow>=9.1
23
+ Requires-Dist: rasterio>=1.3
24
+ Requires-Dist: pyproj>=3.5
25
+ Requires-Dist: shapely>=2.0
26
+ Requires-Dist: trimesh>=4.0
27
+ Requires-Dist: contourpy>=1.1
28
+ Requires-Dist: ezdxf>=1.1
29
+ Requires-Dist: laspy[lazrs]>=2.4
30
+ Requires-Dist: sqlalchemy>=2.0
31
+ Requires-Dist: typer>=0.9
32
+ Provides-Extra: mesh
33
+ Requires-Dist: open3d!=0.20.0,>=0.18; extra == "mesh"
34
+ Provides-Extra: bim
35
+ Requires-Dist: ifcopenshell>=0.8; extra == "bim"
36
+ Provides-Extra: postgis
37
+ Requires-Dist: psycopg2-binary>=2.9; extra == "postgis"
38
+ Provides-Extra: sam
39
+ Requires-Dist: torch>=2.3; extra == "sam"
40
+ Requires-Dist: sam2>=1.1; extra == "sam"
41
+ Provides-Extra: gui
42
+ Requires-Dist: PySide6>=6.6; extra == "gui"
43
+ Requires-Dist: pyvista>=0.43; extra == "gui"
44
+ Requires-Dist: pyvistaqt>=0.13; extra == "gui"
45
+ Requires-Dist: qtawesome>=1.3; extra == "gui"
46
+ Provides-Extra: all
47
+ Requires-Dist: open3d!=0.20.0,>=0.18; extra == "all"
48
+ Requires-Dist: ifcopenshell>=0.8; extra == "all"
49
+ Requires-Dist: psycopg2-binary>=2.9; extra == "all"
50
+ Requires-Dist: PySide6>=6.6; extra == "all"
51
+ Requires-Dist: pyvista>=0.43; extra == "all"
52
+ Requires-Dist: pyvistaqt>=0.13; extra == "all"
53
+ Requires-Dist: qtawesome>=1.3; extra == "all"
54
+ Provides-Extra: dev
55
+ Requires-Dist: pytest>=7; extra == "dev"
56
+ Provides-Extra: build
57
+ Requires-Dist: pyinstaller>=6.10; extra == "build"
58
+ Requires-Dist: pyinstaller-hooks-contrib>=2024.8; extra == "build"
59
+ Requires-Dist: pillow>=9.1; extra == "build"
60
+ Dynamic: license-file
61
+
62
+ # pyarchinit-photogrammetry
63
+
64
+ Open-source photogrammetry engine for archaeology and heritage BIM, integrated with
65
+ [PyArchInit](https://github.com/pyarchinit/pyarchinit).
66
+
67
+ From photos to georeferenced point clouds, meshes, DEMs and orthophotos, with the tools an
68
+ excavation needs: coded targets, ground control, sections, pottery profiles, contour lines,
69
+ cut/fill volumes, point-cloud classification, Segment Anything 2.1, IFC export, and direct
70
+ publishing into a PyArchInit database. Everything is scriptable in Python and runs on CPU,
71
+ Apple Silicon included.
72
+
73
+ > Status: **alpha (0.3)**. Python library, command line and desktop application (on the same
74
+ > API, with a built-in Python console). Italian version: [README.it.md](README.it.md).
75
+
76
+ ## Desktop application (no Python needed)
77
+
78
+ Download the build for your system from the
79
+ [Releases](https://github.com/enzococca/pyarchinit-photogrammetry/releases) page:
80
+
81
+ | Platform | File |
82
+ | --- | --- |
83
+ | macOS 15 or newer (Apple Silicon) | `PyArchInit-Photogrammetry-<version>-macos-arm64.dmg` |
84
+ | Windows 10/11 (64 bit) | `PyArchInit-Photogrammetry-<version>-windows-x64.zip` |
85
+
86
+ Open the disk image and drag the app to *Applications* (macOS), or unzip and run
87
+ `PyArchInit Photogrammetry.exe` (Windows). The application starts on a page with *Nuovo
88
+ progetto*, *Apri progetto* and *Progetto demo*: the demo creates a synthetic trench and a
89
+ bowl on a turntable and processes them in a few minutes. If PyArchInit 5 is installed
90
+ (`~/pyarchinit_5`), the interface connects to its database at start and the demo database is
91
+ written inside `pyarchinit_DB_folder` so that QGIS can open it too; PostgreSQL/PostGIS servers
92
+ are reachable from *PyArchInit > Connetti*. The builds are unsigned: on macOS right-click > *Open*
93
+ the first time (or `xattr -dr com.apple.quarantine "/Applications/PyArchInit Photogrammetry.app"`),
94
+ on Windows choose *More info > Run anyway*. Details in [docs/packaging.md](docs/packaging.md).
95
+
96
+ ## Installation with pip
97
+
98
+ Use a dedicated virtual environment (not the Anaconda `base` environment, see
99
+ *Troubleshooting*). With [uv](https://docs.astral.sh/uv/):
100
+
101
+ ```bash
102
+ uv venv --seed --python 3.12 ~/venvs/ppg && source ~/venvs/ppg/bin/activate
103
+ uv pip install "pyarchinit-photogrammetry[all]" # engine, mesh (Open3D), IFC, PostGIS, desktop GUI
104
+ ```
105
+
106
+ With the standard tools:
107
+
108
+ ```bash
109
+ python3 -m venv ~/venvs/ppg && source ~/venvs/ppg/bin/activate # Windows: ~\venvs\ppg\Scripts\activate
110
+ pip install -U pip && pip install "pyarchinit-photogrammetry[all]"
111
+ ```
112
+
113
+ Optional: `pip install "pyarchinit-photogrammetry[sam]"` adds Segment Anything 2.1 (PyTorch).
114
+ A global `ppg`/`ppg-gui` without activating anything: `uv tool install "pyarchinit-photogrammetry[all]"`
115
+ (or `pipx install`).
116
+
117
+ From source:
118
+
119
+ ```bash
120
+ git clone https://github.com/enzococca/pyarchinit-photogrammetry
121
+ cd pyarchinit-photogrammetry
122
+ uv venv --seed --python 3.12 .venv && source .venv/bin/activate
123
+ uv pip install -e ".[all,dev]"
124
+ pytest -q
125
+ ```
126
+
127
+ Python 3.10-3.12. Writing geometries into a PyArchInit **SQLite** database needs `mod_spatialite`
128
+ (found automatically in QGIS, MacPorts, Homebrew and Linux locations, or set
129
+ `SPATIALITE_LIBRARY_PATH`). On headless Linux servers Open3D needs the EGL/GL libraries:
130
+ `sudo apt-get install libegl1 libgl1 libgomp1`.
131
+
132
+ ## Start
133
+
134
+ ```bash
135
+ ppg doctor # checks the environment and says what to fix
136
+ ppg demo ~/ppg_demo --process # synthetic trench + 8 targets, bowl on a turntable, pottery meshes, PyArchInit DB
137
+ ppg-gui ~/ppg_demo/scavo.ppg # open the processed trench in the interface
138
+ ppg-gui ~/ppg_demo/ceramica/ceramica.ppg # the bowl (local metric frame from the turntable targets)
139
+ ppg-gui # start page: new, open, demo, recent projects
140
+ ```
141
+
142
+ `ppg-gui` is the same as `ppg gui` and `python -m pyarchinit_photogrammetry.gui`. The
143
+ interface writes a log in `~/Library/Logs/pyarchinit-photogrammetry` (macOS),
144
+ `%LOCALAPPDATA%\pyarchinit-photogrammetry\logs` (Windows) or `~/.local/state/pyarchinit-photogrammetry/logs`
145
+ (Linux); *Aiuto > Apri cartella dei log* opens it.
146
+
147
+ ## Troubleshooting
148
+
149
+ * **`ppg-gui` does nothing, or crashes on start.** Run `ppg doctor`. A frequent cause is an
150
+ old copy of the package installed in another Python (for example Anaconda's `base`) that
151
+ comes first on `PATH`: activate the right environment (`which ppg-gui` must point inside it)
152
+ or uninstall the other copy (`/opt/anaconda3/bin/python -m pip uninstall pyarchinit-photogrammetry`).
153
+ * **Anaconda `base` environment**: its SciPy wheels may not load on recent macOS
154
+ (`ImportError ... __thread_bss ... zero-fill section`) and its PROJ data is picked up by
155
+ rasterio. Use a dedicated virtual environment; `PROJ_LIB`/`PROJ_DATA`/`GDAL_DATA` exported
156
+ by Anaconda or QGIS are redirected to the data bundled with rasterio.
157
+ * **The mesh step says "Poisson reconstruction failed... height field instead".** Poisson
158
+ reconstruction runs in a separate process because PoissonRecon (Open3D) can crash on some
159
+ clouds; the pipeline retries and then builds a 2.5D surface. Open3D 0.20.0 crashes
160
+ systematically on macOS and is excluded (`open3d!=0.20.0`); 0.19 works.
161
+ * **Native dialogs crashing on macOS 26/27** (`NSInternalInconsistencyException ...
162
+ targetSizeInPoints`): the interface uses Qt's own message boxes, no action needed.
163
+ * **The 3D view hangs on macOS**: pyvistaqt older than 0.13 hangs on start; `pip install -U pyvistaqt`.
164
+
165
+ ## Screenshots
166
+
167
+ | | |
168
+ | --- | --- |
169
+ | ![Start page](docs/img/gui-start.png) | ![Layers, sections and PyArchInit](docs/img/gui-layers.png) |
170
+ | ![Connection to PyArchInit](docs/img/connect.png) | ![IFC elements per stratigraphic unit](docs/img/ifc-units.png) |
171
+ | ![Bowl from the turntable demo](docs/img/gui-pottery.png) | ![Profile drawing of the bowl](docs/img/demo-profile.png) |
172
+
173
+ Top right: the orthomosaic/DEM view with the US polygons loaded from PyArchInit, contour lines
174
+ and a section trace as layers, the *Sezioni* pane with the drawing, and the PyArchInit pane.
175
+ Middle right: the IFC export opened with IfcOpenShell, one element per unit. Bottom: the bowl
176
+ of the turntable demo reconstructed from 32 synthetic photos and its profile drawing (rim
177
+ 16.0 cm measured against 16.0 cm true).
178
+
179
+ ## Working with QGIS, Metashape, WebODM and Photo3D
180
+
181
+ * **QGIS, live**: *QGIS > Apri in QGIS* opens orthophoto, DEM and every drawn layer in a QGIS
182
+ project; drawings and attribute edits appear in QGIS within a second.
183
+ * **Metashape**: *File > Importa > Progetto Metashape* reads a `.psx` directly (calibrated
184
+ cameras, markers, tie points, model, exported DEM/orthophoto) and continues here (dense
185
+ cloud, sections, PyArchInit, IFC) without aligning again.
186
+ * **WebODM/ODM**: the task folder or `all.zip` becomes a project with orthophoto, DEM, point
187
+ cloud and mesh.
188
+ * **Photo3D**: `ppg photo3d-job` is a ready Photo3D engine; sessions can also be imported.
189
+
190
+ Details in [docs/integrations.md](docs/integrations.md). In the packaged application, SAM 2.1
191
+ is installed on first use (PyTorch in a separate environment, see the same page).
192
+
193
+ ## Desktop interface
194
+
195
+ `ppg-gui` opens the desktop application (Italian UI): start page with recent projects; a
196
+ toolbar with the workflow (photos, markers, alignment, references, dense cloud, model,
197
+ texture, DEM, orthophoto, *Elabora tutto*); workspace with chunks, cameras, markers and
198
+ products; 3D view (VTK, with a software fallback renderer); orthomosaic and DEM view with
199
+ drawing tools (stratigraphic units, section traces, measurements, spot heights, SAM 2.1
200
+ prompts); photo view with manual marker placement; reference pane with GCP and check point
201
+ errors; Python console bound to the project (`doc`, `chunk`); background processing with
202
+ progress, cancel and a status-bar indicator; a drawing toolbar and a *Layer* pane (show/hide,
203
+ zoom, attributes on click) for units, sections, contour lines and spot heights; a *Sezioni*
204
+ pane with the drawings; a log pane with level filter, search, copy and
205
+ save; error windows with a hint, the traceback and a *Copia* button; light and dark themes;
206
+ *Aiuto > Diagnostica ambiente* (the same checks as `ppg doctor`); a PyArchInit menu to
207
+ connect, publish orthophotos, DEMs and models, and write unit polygons and spot heights.
208
+ See [docs/gui.md](docs/gui.md).
209
+
210
+ ## Quick start (Python)
211
+
212
+ ```python
213
+ import pyarchinit_photogrammetry as ppg
214
+
215
+ doc = ppg.Document()
216
+ chunk = doc.add_chunk("Saggio 1")
217
+ chunk.add_photos(["foto/"])
218
+ chunk.detect_markers("aruco_4x4_50") # coded targets, decoded automatically
219
+ chunk.match_photos(quality="high")
220
+ chunk.align_cameras()
221
+ chunk.import_reference("gcp.csv", crs="EPSG:3004")
222
+ report = chunk.update_transform() # GCP georeferencing + accuracy report
223
+ print(report["control_rmse"])
224
+
225
+ chunk.build_depth_maps(quality="medium")
226
+ chunk.build_point_cloud()
227
+ chunk.build_model() # Poisson; surface="height_field" for terrain
228
+ chunk.build_texture()
229
+ chunk.build_dem() # GeoTIFF in the chunk CRS
230
+ chunk.build_orthomosaic() # GeoTIFF RGBA, true-ortho with occlusion test
231
+ chunk.generate_report("report.html")
232
+ doc.save("scavo.ppg")
233
+ ```
234
+
235
+ The same workflow from the command line:
236
+
237
+ ```bash
238
+ ppg markers sheet targets.pdf --codes 0-23 --size-mm 40 # print the targets
239
+ ppg process scavo.ppg foto/ --gcp gcp.csv --crs EPSG:3004 # whole pipeline + report
240
+ ppg export scavo.ppg --ortho ortho.tif --dem dem.tif --model model.obj --cloud cloud.las
241
+ ```
242
+
243
+ Scripts can work on an open project, as in the GUI: `ppg run myscript.py --project scavo.ppg`,
244
+ then `ppg.app.document` inside the script (in the GUI: **Strumenti > Esegui script Python**).
245
+
246
+ ## What it does
247
+
248
+ | Area | Features |
249
+ | --- | --- |
250
+ | Alignment | SIFT features and matching, incremental SfM (COLMAP via pycolmap), camera calibration, bundle adjustment, tie points, pair selection (exhaustive, sequential, by GNSS position) |
251
+ | Dense | Depth maps and fusion on CPU (built-in), COLMAP PatchMatch on NVIDIA GPUs, OpenMVS when installed |
252
+ | Products | Point cloud (PLY/LAS 1.4 with classes), mesh (Poisson in an isolated process with automatic fallback, or 2.5D), texture atlas (OBJ+MTL+JPG), DEM, orthomosaic, hillshade, slope, HTML report |
253
+ | Markers | Printable ArUco/AprilTag sheets with scale bar, turntable mats with known layout, sub-pixel detection, triangulation, GCP/check points, scale bars, weighted 7-parameter transformation, any EPSG CRS (geographic GCPs go to the UTM zone) |
254
+ | Archaeology | Vertical sections and parallel cross sections, plan slices at a given elevation, DXF/SVG drawings at scale, contour lines, cut/fill volumes, 3D proxies of stratigraphic units (closed solids, Extended Matrix OBJ), pottery: rotation axis from sherds, profile, rim/base diameter, height, wall thickness, drawing with filled section |
255
+ | BIM | IFC4 export with IfcMapConversion + IfcProjectedCRS georeferencing, one element per stratigraphic unit with `Pset_PyArchInit_US`; with US proxies, closed solids carrying quantities (`Qto_PyArchInit_US`: volume, area, height, elevations), materials, period/phase groups and stratigraphic relationships (see [docs/bim.md](docs/bim.md)) |
256
+ | AI | Rule-based classification (ground, vegetation, masonry, noise) with archaeological LAS classes 64-71; Segment Anything 2.1 on orthomosaics and photos, masks projected to the point cloud, automatic candidate units |
257
+ | PyArchInit | Reads `config.cfg` and the database (SQLite/SpatiaLite or PostgreSQL/PostGIS) without QGIS; creates and edits US forms with their stratigraphic relationships; publishes orthophotos, DEMs, 3D models and US proxies as media with PyArchInit thumbnails, documentation records and footprints, US links, US polygons, spot heights, section traces, volumes |
258
+
259
+ ## PyArchInit integration
260
+
261
+ ```python
262
+ from pyarchinit_photogrammetry.pyarchinit import PyArchInit
263
+
264
+ pa = PyArchInit.connect() # the database configured in PyArchInit
265
+ pa.publish_orthomosaic(chunk, sito="Lagoi", nome_doc="Ortofoto saggio 1",
266
+ link_us=[("1", "101"), ("1", "102")])
267
+ pa.publish_dem(chunk, sito="Lagoi", nome_doc="DEM saggio 1")
268
+ pa.publish_model(chunk, sito="Lagoi", nome_doc="Modello saggio 1")
269
+ units = pa.us_polygons("Lagoi") # US polygons as shapely geometries
270
+ ```
271
+
272
+ Conventions follow PyArchInit 5 (branch `Stratigraph_00001`): `media_table`,
273
+ `media_thumb_table` (`{id}_{name}_thumb.png` 150 px, `{id}_{name}.png` 2008x1417),
274
+ `media_to_entity_table` (`US`/`us_table`, `REPERTO`, `CERAMICA`, ...), `documentazione_table`
275
+ (`Fotopiano`, `DEM`, `Modello tridimensionale`, source `Fotogrammetria`), footprints in
276
+ `pyarchinit_documentazione`, polygons in `pyunitastratigrafiche`, heights in
277
+ `pyarchinit_quote`, sections in `pyarchinit_sezioni`, volumes in `computo_metrico_table`.
278
+ `entity_uuid` is filled when the column exists. Rasters are copied next to the thumbnail
279
+ folder (`<media>/fotogrammetria/<site>/`). See [docs/pyarchinit.md](docs/pyarchinit.md).
280
+
281
+ ## Pottery from a turntable
282
+
283
+ ```bash
284
+ ppg markers turntable mat.pdf --n 12 --diameter-mm 180 # also writes mat.csv
285
+ ```
286
+
287
+ Photograph the vessel or sherd on the mat, process with `--gcp mat.csv` (local frame, mm
288
+ accuracy), then:
289
+
290
+ ```bash
291
+ ppg pottery model.obj --out profilo.svg --scale 1 --title "US 101 n. 34"
292
+ ```
293
+
294
+ The axis is estimated from the surface normals (works on sherds); with the turntable you
295
+ can impose it with `--axis 0,0,0,0,0,1`.
296
+
297
+ ## Accuracy check
298
+
299
+ The test suite renders a synthetic trench (4 x 3 m, a wall stub, 8 targets at known
300
+ EPSG:3004 coordinates, 28 photos with lens distortion) and checks the products
301
+ metrically: all photos aligned, control RMSE < 2 mm, independent check points < 3 mm, DEM
302
+ median error < 3 mm, orthophoto target positions < 5 mm.
303
+
304
+ ## Architecture
305
+
306
+ ```
307
+ pyarchinit_photogrammetry/
308
+ core/ Document, Chunk, Camera, Sensor, Marker, ScaleBar, PointCloud, CRS
309
+ engine/ sfm (pycolmap), dense, meshing, isolate (crash-proof workers), texturing, dem, ortho
310
+ markers/ coded targets, GCP import/export, georeferencing
311
+ archaeo/ sections, pottery, terrain (contours, volumes), stratigraphy (units)
312
+ bim/ IFC export
313
+ ai/ classification, SAM 2.1
314
+ pyarchinit/ config.cfg, database, media, high-level bridge
315
+ io/ EXIF, exports, report
316
+ gui/ desktop interface (PySide6, pyvista, qtawesome icons, themes, log, start page)
317
+ doctor.py environment diagnosis (`ppg doctor`)
318
+ demo.py demo data set
319
+ cli.py `ppg` command
320
+ packaging/ PyInstaller spec and build script for the desktop application
321
+ ```
322
+
323
+ Projects are a JSON file (`name.ppg`) plus a folder (`name.ppg.files/`) with the data of each
324
+ chunk; photo paths inside the project folder are stored relative, so projects can be moved.
325
+
326
+ ## License
327
+
328
+ GNU GPL v2 or later, like PyArchInit. Third-party engines keep their licences (COLMAP BSD,
329
+ OpenMVS AGPL when used as an external program, SAM 2.1 Apache 2.0).
330
+
331
+ Author: Enzo Cocca
@@ -0,0 +1,270 @@
1
+ # pyarchinit-photogrammetry
2
+
3
+ Open-source photogrammetry engine for archaeology and heritage BIM, integrated with
4
+ [PyArchInit](https://github.com/pyarchinit/pyarchinit).
5
+
6
+ From photos to georeferenced point clouds, meshes, DEMs and orthophotos, with the tools an
7
+ excavation needs: coded targets, ground control, sections, pottery profiles, contour lines,
8
+ cut/fill volumes, point-cloud classification, Segment Anything 2.1, IFC export, and direct
9
+ publishing into a PyArchInit database. Everything is scriptable in Python and runs on CPU,
10
+ Apple Silicon included.
11
+
12
+ > Status: **alpha (0.3)**. Python library, command line and desktop application (on the same
13
+ > API, with a built-in Python console). Italian version: [README.it.md](README.it.md).
14
+
15
+ ## Desktop application (no Python needed)
16
+
17
+ Download the build for your system from the
18
+ [Releases](https://github.com/enzococca/pyarchinit-photogrammetry/releases) page:
19
+
20
+ | Platform | File |
21
+ | --- | --- |
22
+ | macOS 15 or newer (Apple Silicon) | `PyArchInit-Photogrammetry-<version>-macos-arm64.dmg` |
23
+ | Windows 10/11 (64 bit) | `PyArchInit-Photogrammetry-<version>-windows-x64.zip` |
24
+
25
+ Open the disk image and drag the app to *Applications* (macOS), or unzip and run
26
+ `PyArchInit Photogrammetry.exe` (Windows). The application starts on a page with *Nuovo
27
+ progetto*, *Apri progetto* and *Progetto demo*: the demo creates a synthetic trench and a
28
+ bowl on a turntable and processes them in a few minutes. If PyArchInit 5 is installed
29
+ (`~/pyarchinit_5`), the interface connects to its database at start and the demo database is
30
+ written inside `pyarchinit_DB_folder` so that QGIS can open it too; PostgreSQL/PostGIS servers
31
+ are reachable from *PyArchInit > Connetti*. The builds are unsigned: on macOS right-click > *Open*
32
+ the first time (or `xattr -dr com.apple.quarantine "/Applications/PyArchInit Photogrammetry.app"`),
33
+ on Windows choose *More info > Run anyway*. Details in [docs/packaging.md](docs/packaging.md).
34
+
35
+ ## Installation with pip
36
+
37
+ Use a dedicated virtual environment (not the Anaconda `base` environment, see
38
+ *Troubleshooting*). With [uv](https://docs.astral.sh/uv/):
39
+
40
+ ```bash
41
+ uv venv --seed --python 3.12 ~/venvs/ppg && source ~/venvs/ppg/bin/activate
42
+ uv pip install "pyarchinit-photogrammetry[all]" # engine, mesh (Open3D), IFC, PostGIS, desktop GUI
43
+ ```
44
+
45
+ With the standard tools:
46
+
47
+ ```bash
48
+ python3 -m venv ~/venvs/ppg && source ~/venvs/ppg/bin/activate # Windows: ~\venvs\ppg\Scripts\activate
49
+ pip install -U pip && pip install "pyarchinit-photogrammetry[all]"
50
+ ```
51
+
52
+ Optional: `pip install "pyarchinit-photogrammetry[sam]"` adds Segment Anything 2.1 (PyTorch).
53
+ A global `ppg`/`ppg-gui` without activating anything: `uv tool install "pyarchinit-photogrammetry[all]"`
54
+ (or `pipx install`).
55
+
56
+ From source:
57
+
58
+ ```bash
59
+ git clone https://github.com/enzococca/pyarchinit-photogrammetry
60
+ cd pyarchinit-photogrammetry
61
+ uv venv --seed --python 3.12 .venv && source .venv/bin/activate
62
+ uv pip install -e ".[all,dev]"
63
+ pytest -q
64
+ ```
65
+
66
+ Python 3.10-3.12. Writing geometries into a PyArchInit **SQLite** database needs `mod_spatialite`
67
+ (found automatically in QGIS, MacPorts, Homebrew and Linux locations, or set
68
+ `SPATIALITE_LIBRARY_PATH`). On headless Linux servers Open3D needs the EGL/GL libraries:
69
+ `sudo apt-get install libegl1 libgl1 libgomp1`.
70
+
71
+ ## Start
72
+
73
+ ```bash
74
+ ppg doctor # checks the environment and says what to fix
75
+ ppg demo ~/ppg_demo --process # synthetic trench + 8 targets, bowl on a turntable, pottery meshes, PyArchInit DB
76
+ ppg-gui ~/ppg_demo/scavo.ppg # open the processed trench in the interface
77
+ ppg-gui ~/ppg_demo/ceramica/ceramica.ppg # the bowl (local metric frame from the turntable targets)
78
+ ppg-gui # start page: new, open, demo, recent projects
79
+ ```
80
+
81
+ `ppg-gui` is the same as `ppg gui` and `python -m pyarchinit_photogrammetry.gui`. The
82
+ interface writes a log in `~/Library/Logs/pyarchinit-photogrammetry` (macOS),
83
+ `%LOCALAPPDATA%\pyarchinit-photogrammetry\logs` (Windows) or `~/.local/state/pyarchinit-photogrammetry/logs`
84
+ (Linux); *Aiuto > Apri cartella dei log* opens it.
85
+
86
+ ## Troubleshooting
87
+
88
+ * **`ppg-gui` does nothing, or crashes on start.** Run `ppg doctor`. A frequent cause is an
89
+ old copy of the package installed in another Python (for example Anaconda's `base`) that
90
+ comes first on `PATH`: activate the right environment (`which ppg-gui` must point inside it)
91
+ or uninstall the other copy (`/opt/anaconda3/bin/python -m pip uninstall pyarchinit-photogrammetry`).
92
+ * **Anaconda `base` environment**: its SciPy wheels may not load on recent macOS
93
+ (`ImportError ... __thread_bss ... zero-fill section`) and its PROJ data is picked up by
94
+ rasterio. Use a dedicated virtual environment; `PROJ_LIB`/`PROJ_DATA`/`GDAL_DATA` exported
95
+ by Anaconda or QGIS are redirected to the data bundled with rasterio.
96
+ * **The mesh step says "Poisson reconstruction failed... height field instead".** Poisson
97
+ reconstruction runs in a separate process because PoissonRecon (Open3D) can crash on some
98
+ clouds; the pipeline retries and then builds a 2.5D surface. Open3D 0.20.0 crashes
99
+ systematically on macOS and is excluded (`open3d!=0.20.0`); 0.19 works.
100
+ * **Native dialogs crashing on macOS 26/27** (`NSInternalInconsistencyException ...
101
+ targetSizeInPoints`): the interface uses Qt's own message boxes, no action needed.
102
+ * **The 3D view hangs on macOS**: pyvistaqt older than 0.13 hangs on start; `pip install -U pyvistaqt`.
103
+
104
+ ## Screenshots
105
+
106
+ | | |
107
+ | --- | --- |
108
+ | ![Start page](docs/img/gui-start.png) | ![Layers, sections and PyArchInit](docs/img/gui-layers.png) |
109
+ | ![Connection to PyArchInit](docs/img/connect.png) | ![IFC elements per stratigraphic unit](docs/img/ifc-units.png) |
110
+ | ![Bowl from the turntable demo](docs/img/gui-pottery.png) | ![Profile drawing of the bowl](docs/img/demo-profile.png) |
111
+
112
+ Top right: the orthomosaic/DEM view with the US polygons loaded from PyArchInit, contour lines
113
+ and a section trace as layers, the *Sezioni* pane with the drawing, and the PyArchInit pane.
114
+ Middle right: the IFC export opened with IfcOpenShell, one element per unit. Bottom: the bowl
115
+ of the turntable demo reconstructed from 32 synthetic photos and its profile drawing (rim
116
+ 16.0 cm measured against 16.0 cm true).
117
+
118
+ ## Working with QGIS, Metashape, WebODM and Photo3D
119
+
120
+ * **QGIS, live**: *QGIS > Apri in QGIS* opens orthophoto, DEM and every drawn layer in a QGIS
121
+ project; drawings and attribute edits appear in QGIS within a second.
122
+ * **Metashape**: *File > Importa > Progetto Metashape* reads a `.psx` directly (calibrated
123
+ cameras, markers, tie points, model, exported DEM/orthophoto) and continues here (dense
124
+ cloud, sections, PyArchInit, IFC) without aligning again.
125
+ * **WebODM/ODM**: the task folder or `all.zip` becomes a project with orthophoto, DEM, point
126
+ cloud and mesh.
127
+ * **Photo3D**: `ppg photo3d-job` is a ready Photo3D engine; sessions can also be imported.
128
+
129
+ Details in [docs/integrations.md](docs/integrations.md). In the packaged application, SAM 2.1
130
+ is installed on first use (PyTorch in a separate environment, see the same page).
131
+
132
+ ## Desktop interface
133
+
134
+ `ppg-gui` opens the desktop application (Italian UI): start page with recent projects; a
135
+ toolbar with the workflow (photos, markers, alignment, references, dense cloud, model,
136
+ texture, DEM, orthophoto, *Elabora tutto*); workspace with chunks, cameras, markers and
137
+ products; 3D view (VTK, with a software fallback renderer); orthomosaic and DEM view with
138
+ drawing tools (stratigraphic units, section traces, measurements, spot heights, SAM 2.1
139
+ prompts); photo view with manual marker placement; reference pane with GCP and check point
140
+ errors; Python console bound to the project (`doc`, `chunk`); background processing with
141
+ progress, cancel and a status-bar indicator; a drawing toolbar and a *Layer* pane (show/hide,
142
+ zoom, attributes on click) for units, sections, contour lines and spot heights; a *Sezioni*
143
+ pane with the drawings; a log pane with level filter, search, copy and
144
+ save; error windows with a hint, the traceback and a *Copia* button; light and dark themes;
145
+ *Aiuto > Diagnostica ambiente* (the same checks as `ppg doctor`); a PyArchInit menu to
146
+ connect, publish orthophotos, DEMs and models, and write unit polygons and spot heights.
147
+ See [docs/gui.md](docs/gui.md).
148
+
149
+ ## Quick start (Python)
150
+
151
+ ```python
152
+ import pyarchinit_photogrammetry as ppg
153
+
154
+ doc = ppg.Document()
155
+ chunk = doc.add_chunk("Saggio 1")
156
+ chunk.add_photos(["foto/"])
157
+ chunk.detect_markers("aruco_4x4_50") # coded targets, decoded automatically
158
+ chunk.match_photos(quality="high")
159
+ chunk.align_cameras()
160
+ chunk.import_reference("gcp.csv", crs="EPSG:3004")
161
+ report = chunk.update_transform() # GCP georeferencing + accuracy report
162
+ print(report["control_rmse"])
163
+
164
+ chunk.build_depth_maps(quality="medium")
165
+ chunk.build_point_cloud()
166
+ chunk.build_model() # Poisson; surface="height_field" for terrain
167
+ chunk.build_texture()
168
+ chunk.build_dem() # GeoTIFF in the chunk CRS
169
+ chunk.build_orthomosaic() # GeoTIFF RGBA, true-ortho with occlusion test
170
+ chunk.generate_report("report.html")
171
+ doc.save("scavo.ppg")
172
+ ```
173
+
174
+ The same workflow from the command line:
175
+
176
+ ```bash
177
+ ppg markers sheet targets.pdf --codes 0-23 --size-mm 40 # print the targets
178
+ ppg process scavo.ppg foto/ --gcp gcp.csv --crs EPSG:3004 # whole pipeline + report
179
+ ppg export scavo.ppg --ortho ortho.tif --dem dem.tif --model model.obj --cloud cloud.las
180
+ ```
181
+
182
+ Scripts can work on an open project, as in the GUI: `ppg run myscript.py --project scavo.ppg`,
183
+ then `ppg.app.document` inside the script (in the GUI: **Strumenti > Esegui script Python**).
184
+
185
+ ## What it does
186
+
187
+ | Area | Features |
188
+ | --- | --- |
189
+ | Alignment | SIFT features and matching, incremental SfM (COLMAP via pycolmap), camera calibration, bundle adjustment, tie points, pair selection (exhaustive, sequential, by GNSS position) |
190
+ | Dense | Depth maps and fusion on CPU (built-in), COLMAP PatchMatch on NVIDIA GPUs, OpenMVS when installed |
191
+ | Products | Point cloud (PLY/LAS 1.4 with classes), mesh (Poisson in an isolated process with automatic fallback, or 2.5D), texture atlas (OBJ+MTL+JPG), DEM, orthomosaic, hillshade, slope, HTML report |
192
+ | Markers | Printable ArUco/AprilTag sheets with scale bar, turntable mats with known layout, sub-pixel detection, triangulation, GCP/check points, scale bars, weighted 7-parameter transformation, any EPSG CRS (geographic GCPs go to the UTM zone) |
193
+ | Archaeology | Vertical sections and parallel cross sections, plan slices at a given elevation, DXF/SVG drawings at scale, contour lines, cut/fill volumes, 3D proxies of stratigraphic units (closed solids, Extended Matrix OBJ), pottery: rotation axis from sherds, profile, rim/base diameter, height, wall thickness, drawing with filled section |
194
+ | BIM | IFC4 export with IfcMapConversion + IfcProjectedCRS georeferencing, one element per stratigraphic unit with `Pset_PyArchInit_US`; with US proxies, closed solids carrying quantities (`Qto_PyArchInit_US`: volume, area, height, elevations), materials, period/phase groups and stratigraphic relationships (see [docs/bim.md](docs/bim.md)) |
195
+ | AI | Rule-based classification (ground, vegetation, masonry, noise) with archaeological LAS classes 64-71; Segment Anything 2.1 on orthomosaics and photos, masks projected to the point cloud, automatic candidate units |
196
+ | PyArchInit | Reads `config.cfg` and the database (SQLite/SpatiaLite or PostgreSQL/PostGIS) without QGIS; creates and edits US forms with their stratigraphic relationships; publishes orthophotos, DEMs, 3D models and US proxies as media with PyArchInit thumbnails, documentation records and footprints, US links, US polygons, spot heights, section traces, volumes |
197
+
198
+ ## PyArchInit integration
199
+
200
+ ```python
201
+ from pyarchinit_photogrammetry.pyarchinit import PyArchInit
202
+
203
+ pa = PyArchInit.connect() # the database configured in PyArchInit
204
+ pa.publish_orthomosaic(chunk, sito="Lagoi", nome_doc="Ortofoto saggio 1",
205
+ link_us=[("1", "101"), ("1", "102")])
206
+ pa.publish_dem(chunk, sito="Lagoi", nome_doc="DEM saggio 1")
207
+ pa.publish_model(chunk, sito="Lagoi", nome_doc="Modello saggio 1")
208
+ units = pa.us_polygons("Lagoi") # US polygons as shapely geometries
209
+ ```
210
+
211
+ Conventions follow PyArchInit 5 (branch `Stratigraph_00001`): `media_table`,
212
+ `media_thumb_table` (`{id}_{name}_thumb.png` 150 px, `{id}_{name}.png` 2008x1417),
213
+ `media_to_entity_table` (`US`/`us_table`, `REPERTO`, `CERAMICA`, ...), `documentazione_table`
214
+ (`Fotopiano`, `DEM`, `Modello tridimensionale`, source `Fotogrammetria`), footprints in
215
+ `pyarchinit_documentazione`, polygons in `pyunitastratigrafiche`, heights in
216
+ `pyarchinit_quote`, sections in `pyarchinit_sezioni`, volumes in `computo_metrico_table`.
217
+ `entity_uuid` is filled when the column exists. Rasters are copied next to the thumbnail
218
+ folder (`<media>/fotogrammetria/<site>/`). See [docs/pyarchinit.md](docs/pyarchinit.md).
219
+
220
+ ## Pottery from a turntable
221
+
222
+ ```bash
223
+ ppg markers turntable mat.pdf --n 12 --diameter-mm 180 # also writes mat.csv
224
+ ```
225
+
226
+ Photograph the vessel or sherd on the mat, process with `--gcp mat.csv` (local frame, mm
227
+ accuracy), then:
228
+
229
+ ```bash
230
+ ppg pottery model.obj --out profilo.svg --scale 1 --title "US 101 n. 34"
231
+ ```
232
+
233
+ The axis is estimated from the surface normals (works on sherds); with the turntable you
234
+ can impose it with `--axis 0,0,0,0,0,1`.
235
+
236
+ ## Accuracy check
237
+
238
+ The test suite renders a synthetic trench (4 x 3 m, a wall stub, 8 targets at known
239
+ EPSG:3004 coordinates, 28 photos with lens distortion) and checks the products
240
+ metrically: all photos aligned, control RMSE < 2 mm, independent check points < 3 mm, DEM
241
+ median error < 3 mm, orthophoto target positions < 5 mm.
242
+
243
+ ## Architecture
244
+
245
+ ```
246
+ pyarchinit_photogrammetry/
247
+ core/ Document, Chunk, Camera, Sensor, Marker, ScaleBar, PointCloud, CRS
248
+ engine/ sfm (pycolmap), dense, meshing, isolate (crash-proof workers), texturing, dem, ortho
249
+ markers/ coded targets, GCP import/export, georeferencing
250
+ archaeo/ sections, pottery, terrain (contours, volumes), stratigraphy (units)
251
+ bim/ IFC export
252
+ ai/ classification, SAM 2.1
253
+ pyarchinit/ config.cfg, database, media, high-level bridge
254
+ io/ EXIF, exports, report
255
+ gui/ desktop interface (PySide6, pyvista, qtawesome icons, themes, log, start page)
256
+ doctor.py environment diagnosis (`ppg doctor`)
257
+ demo.py demo data set
258
+ cli.py `ppg` command
259
+ packaging/ PyInstaller spec and build script for the desktop application
260
+ ```
261
+
262
+ Projects are a JSON file (`name.ppg`) plus a folder (`name.ppg.files/`) with the data of each
263
+ chunk; photo paths inside the project folder are stored relative, so projects can be moved.
264
+
265
+ ## License
266
+
267
+ GNU GPL v2 or later, like PyArchInit. Third-party engines keep their licences (COLMAP BSD,
268
+ OpenMVS AGPL when used as an external program, SAM 2.1 Apache 2.0).
269
+
270
+ Author: Enzo Cocca
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "pyarchinit-photogrammetry"
7
- version = "0.2.0"
7
+ version = "0.4.0"
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,20 +31,21 @@ dependencies = [
31
31
  "trimesh>=4.0",
32
32
  "contourpy>=1.1",
33
33
  "ezdxf>=1.1",
34
- "laspy>=2.4",
34
+ "laspy[lazrs]>=2.4",
35
35
  "sqlalchemy>=2.0",
36
36
  "typer>=0.9",
37
37
  ]
38
38
 
39
39
  [project.optional-dependencies]
40
- mesh = ["open3d>=0.18"]
40
+ mesh = ["open3d>=0.18,!=0.20.0"]
41
41
  bim = ["ifcopenshell>=0.8"]
42
42
  postgis = ["psycopg2-binary>=2.9"]
43
43
  sam = ["torch>=2.3", "sam2>=1.1"]
44
- gui = ["PySide6>=6.6", "pyvista>=0.43", "pyvistaqt>=0.11"]
45
- all = ["open3d>=0.18", "ifcopenshell>=0.8", "psycopg2-binary>=2.9", "PySide6>=6.6", "pyvista>=0.43",
46
- "pyvistaqt>=0.11"]
44
+ gui = ["PySide6>=6.6", "pyvista>=0.43", "pyvistaqt>=0.13", "qtawesome>=1.3"]
45
+ all = ["open3d>=0.18,!=0.20.0", "ifcopenshell>=0.8", "psycopg2-binary>=2.9", "PySide6>=6.6", "pyvista>=0.43",
46
+ "pyvistaqt>=0.13", "qtawesome>=1.3"]
47
47
  dev = ["pytest>=7"]
48
+ build = ["pyinstaller>=6.10", "pyinstaller-hooks-contrib>=2024.8", "pillow>=9.1"]
48
49
 
49
50
  [project.scripts]
50
51
  ppg = "pyarchinit_photogrammetry.cli:main"
@@ -59,6 +60,10 @@ Issues = "https://github.com/enzococca/pyarchinit-photogrammetry/issues"
59
60
  [tool.setuptools.packages.find]
60
61
  where = ["src"]
61
62
 
63
+ [tool.setuptools.package-data]
64
+ # files the code reads at run time (tests/test_packaging.py checks that nothing is left out)
65
+ pyarchinit_photogrammetry = ["gui/resources/*", "pyarchinit/*.sql"]
66
+
62
67
  [tool.pytest.ini_options]
63
68
  testpaths = ["tests"]
64
69
  markers = ["slow: end-to-end tests that run the full photogrammetric pipeline"]