Applicazione desktop impacchettata¶
Le versioni pronte all'uso dell'interfaccia, con dentro Python e tutte le librerie, le produce PyInstaller:
| Sistema | File | Avvio |
|---|---|---|
| macOS 15 o successivo (Apple Silicon) | PyArchInit-Photogrammetry-<versione>-macos-arm64.dmg |
apri l'immagine disco e trascina l'app in Applicazioni |
| Windows 10/11 (64 bit) | PyArchInit-Photogrammetry-<versione>-windows-x64.zip |
estrai lo zip e avvia PyArchInit Photogrammetry.exe |
Sono allegate a ogni release su GitHub
e le produce il workflow desktop (.github/workflows/desktop.yml, runner macos-15
e windows-latest). L'applicazione impacchettata contiene lo stesso codice del pacchetto
pip: Open3D, VTK, qtawesome e IfcOpenShell sono inclusi; Segment Anything (PyTorch)
no, e viene installato al primo uso in un ambiente separato (vedi
integrations.md).
Primo avvio¶
- macOS: l'applicazione non è firmata con un certificato di sviluppatore Apple. Gatekeeper mostra "Impossibile aprire ... perché non è possibile verificare lo sviluppatore" (o "è danneggiata" sui sistemi più recenti). Tasto destro sull'app e Apri una volta, oppure togli l'attributo di quarantena dal terminale:
xattr -dr com.apple.quarantine "/Applications/PyArchInit Photogrammetry.app"
-
Windows: SmartScreen può chiedere una conferma la prima volta (Ulteriori informazioni > Esegui comunque). Per scrivere geometrie in un database SQLite di PyArchInit serve
mod_spatialite.dll: viene trovata in un'installazione di QGIS o di OSGeo4W, oppure impostaSPATIALITE_LIBRARY_PATH. -
Windows su ARM (portatili Snapdragon, Windows 11 in Parallels su un Mac con Apple Silicon): l'applicazione x64 gira nell'emulazione di Windows 11 - provata su Windows 11 ARM64 con
--checke--doctor(Python, pycolmap, Open3D, OpenCV, rasterio, Qt e VTK si caricano) e con la finestra.
I log vengono scritti in ~/Library/Logs/pyarchinit-photogrammetry (macOS) o in
%LOCALAPPDATA%\pyarchinit-photogrammetry\logs (Windows); Aiuto > Apri cartella dei log
apre la cartella, Aiuto > Diagnostica ambiente esegue gli stessi controlli di ppg doctor.
L'applicazione esegue anche script Python, con il suo Python e i suoi moduli e senza la
finestra, come fa Metashape con -r (il codice d'uscita è quello dello script):
"/Applications/PyArchInit Photogrammetry.app/Contents/MacOS/PyArchInit Photogrammetry" --run script.py args
"PyArchInit Photogrammetry.exe" --run script.py args > out.txt 2>&1 # Windows: niente console, ridirigi l'output
Costruire in locale¶
pip install -e ".[all,build]"
pip install ./native # kernel nativi (serve la toolchain Rust), inclusi nell'app se installati
python packaging/build.py # icone, PyInstaller, smoke test (--check), dmg/zip in dist/
python packaging/build.py --no-smoke
packaging/ppg_gui.spec: lo spec di PyInstaller (build in una cartella, con finestra, gli hook per i dati di rasterio, pyproj, Open3D, VTK, qtawesome e pycolmap, esclusi i moduli Qt che non si usano).packaging/launcher.py: il punto d'ingresso; chiama per prima cosamultiprocessing.freeze_support(), così i processi di lavoro isolati (ricostruzione di Poisson) funzionano nell'applicazione impacchettata.packaging/build.py: disegna le icone dagui/resources/logo.svg, lancia PyInstaller, riporta a@loader_pathi riferimenti alle librerie private di ogni pacchetto (macOS: rasterio e pyproj portano build diverse dilibprojcon lo stesso nome, e PyInstaller altrimenti gliene farebbe condividere una copia sola), avvia il risultato con--check(offscreen) e--doctor, poi scrive il.dmg(hdiutil) o lo.zip.
Lo smoke test apre la finestra principale, la disegna ed esce con codice 0; la build fallisce
quando la finestra non compare. La sua riga dice anche se dentro c'è il nucleo nativo
(native: 0.1.0).
Nucleo nativo (Rust)¶
native/ contiene pyarchinit-photogrammetry-core, importato come ppg_core: i kernel che il
codice Python eseguiva in numpy e che dominavano il tempo di CPU delle mappe di profondità e
dell'ortofoto - fusione delle stime di profondità di una foto, dalla disparità alla profondità, normali,
proiezione dei punti con i modelli di camera di COLMAP, punteggio delle foto di un tassello
dell'ortofoto, accordo dei punti con una mappa di profondità (confidenza). PyO3 + rayon, una wheel abi3 per
piattaforma per Python 3.10 e successivi. È facoltativo: senza (o con PPG_NATIVE=0) gira il
codice numpy, e tests/test_native.py controlla che i due diano le stesse mappe, gli stessi pixel e gli
stessi conteggi. Misurato sulla trincea sintetica, mappe di profondità su CPU di 48 foto: 5,7 s con numpy una
foto alla volta, 1,6 s con i kernel nativi, 0,9 s con sei foto alla volta.
Dalla 0.2.0 il nucleo contiene anche lo stereo multi-vista PatchMatch (patchmatch_depth, il backend delle
mappe di profondità patchmatch, che la scelta automatica usa per i rilievi aerei: foto le cui posizioni
GPS si distribuiscono sul sito). Non ha una versione numpy (sarebbe troppo lenta): senza il nucleo
auto ripiega sullo SGBM a due viste, il backend non viene offerto nella finestra e il passo si ferma con un
messaggio quando lo si chiede per nome.
pip install ./native # costruisce e installa (maturin lo scarica pip)
maturin build --release -m native/Cargo.toml # una wheel in native/target/wheels
PPG_NATIVE=0 ppg ... # il codice numpy, per confronto
Il profilo di release conserva i simboli: la libreria spogliata dei simboli dal profilo di release predefinito
di Rust viene rifiutata dal loader dinamico di macOS 26/27 ("mis-aligned LINKEDIT string pool"). Il
workflow native costruisce le wheel (macOS arm64 e x86-64, Windows x64, Linux x86-64 e
aarch64) e, su un tag core-v*, le pubblica su PyPI; il workflow tests esegue Python 3.12
con il nucleo nativo e 3.11 senza; il workflow desktop lo include nelle applicazioni.
Linux su ARM (aarch64): pycolmap e Open3D¶
pycolmap 4.2.1 e Open3D 0.19.0 non pubblicano wheel per Linux su ARM (Open3D 0.20.0 sì, ma la sua
ricostruzione di Poisson va in crash e i requisiti la escludono). packaging/arm/build-linux.sh
le costruisce in Docker su una macchina arm64 - un Mac con Apple Silicon, un host Linux arm64 - e
il workflow arm-wheels fa lo stesso sui runner arm64 di GitHub, poi esegue con loro i test di questo
progetto (a richiesta; le wheel restano come artifact, o vengono allegate alla release di cui si dà
il tag).
packaging/arm/build-linux.sh # entrambe, Python 3.10-3.12, wheel in dist/arm
PYTHONS=3.12 JOBS=3 packaging/arm/build-linux.sh pycolmap
packaging/arm/build-linux.sh test # i test con loro (Ubuntu 24.04, Python 3.12)
pip install dist/arm/pycolmap-*-cp312-*.whl dist/arm/open3d-*-cp312-*.whl
pip install "pyarchinit-photogrammetry[all]"
- pycolmap: la ricetta di COLMAP per le sue wheel x86-64 (l'immagine manylinux_2_28, vcpkg, GCC 12)
con un triplet arm64; wheel
manylinux_2_28_aarch64(glibc 2.28 o successiva). - Open3D: la ricetta arm64 di Open3D (Ubuntu 20.04, OpenBLAS, VTK ed Embree costruiti dai sorgenti)
senza la sua GUI nuova (Filament), che questo programma non usa; wheel
manylinux_2_31_aarch64(glibc 2.31 o successiva), nome del pacchettoopen3d. - Il lavoro va in cartelle dell'host, non nel disco di Docker (che tiene solo le due
immagini di build); su un Mac in un'immagine disco case-sensitive,
build/arm.sparseimage, perché i pacchetti Linux contengono nomi che differiscono solo per maiuscole e minuscole (hdiutil detach build/armla chiude). - Alcuni file di COLMAP e Open3D hanno bisogno di parecchi GB ciascuno per compilare:
JOBScompilatori alla volta (3 per impostazione predefinita, per un Docker da 8 GB), quelli che esauriscono la memoria compilati di nuovo da soli. - Open3D su ARM collega la
libgfortrancondivisa (messa nella wheel da auditwheel): con quella statica, come fa la build ARM di Open3D stessa, il modulo non si importa ("cannot allocate memory in static TLS block"). - Anche
pye57(scansioni E57, in[all]) non ha wheel per aarch64: viene compilato all'installazione e ha bisogno degli header di Xerces-C (sudo apt install libxerces-c-devsu Debian e Ubuntu).
Firma, notarizzazione, TestFlight¶
Le build non sono firmate. Le vie Apple sono due:
- Developer ID + notarizzazione (download dal web/GitHub, nessun avviso): serve un
certificato Developer ID Application (creato dall'Account Holder del team Apple
Developer) e un profilo per il notary (
xcrun notarytool store-credentials). PoiPPG_CODESIGN_IDENTITY="Developer ID Application: ... (TEAMID)" PPG_NOTARY_PROFILE=<profile> python packaging/build.pyfirma ogni binario con l'hardened runtime (packaging/entitlements.plist), firma e notarizza il dmg e vi allega (staple) il biglietto. - TestFlight / Mac App Store: servono un certificato Apple Distribution, un profilo di provisioning
e l'App Sandbox. La sandbox vieta ciò su cui questa applicazione si basa:
caricare
mod_spatialiteda Homebrew/QGIS, avviare processi di lavoro da altri interpreti (Poisson isolata, ambiente SAM), scaricare ed eseguireuv, scrivere accanto ai progetti dell'utente senza una finestra di dialogo, aprire QGIS. Un'edizione con sandbox richiederebbe di riprogettare quelle parti, quindi il canale consigliato è Developer ID.