reconstruct3d 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,416 @@
1
+ Metadata-Version: 2.4
2
+ Name: reconstruct3d
3
+ Version: 0.1.0
4
+ Summary: Pipeline offline de reconstrucción 3D desde video monocular: Structure-from-Motion incremental + Bundle Adjustment + densificación MVS + mallado CGAL, con front-ends de features intercambiables (SIFT, ORB, SuperPoint+LightGlue).
5
+ Project-URL: Homepage, https://github.com/FernandoUs/Template-SLAM
6
+ Project-URL: Repository, https://github.com/FernandoUs/Template-SLAM
7
+ Project-URL: Issues, https://github.com/FernandoUs/Template-SLAM/issues
8
+ Author-email: BlackMonkcr <aaron.navarro@utec.edu.pe>
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: 3d-reconstruction,bundle-adjustment,cgal,computer-vision,mvs,opencv,photogrammetry,point-cloud,sfm,structure-from-motion
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Operating System :: OS Independent
16
+ Classifier: Programming Language :: Python :: 3
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
19
+ Classifier: Topic :: Scientific/Engineering :: Image Recognition
20
+ Requires-Python: >=3.10
21
+ Requires-Dist: numpy>=1.26
22
+ Requires-Dist: opencv-contrib-python>=4.8
23
+ Requires-Dist: pandas>=2.0
24
+ Requires-Dist: scipy>=1.11
25
+ Requires-Dist: tqdm>=4.66
26
+ Provides-Extra: api
27
+ Requires-Dist: fastapi>=0.110; extra == 'api'
28
+ Requires-Dist: httpx>=0.27; extra == 'api'
29
+ Requires-Dist: python-multipart>=0.0.9; extra == 'api'
30
+ Requires-Dist: uvicorn[standard]>=0.27; extra == 'api'
31
+ Provides-Extra: spglue
32
+ Requires-Dist: lightglue; extra == 'spglue'
33
+ Requires-Dist: torch>=2.2; extra == 'spglue'
34
+ Requires-Dist: torchvision>=0.17; extra == 'spglue'
35
+ Description-Content-Type: text/markdown
36
+
37
+ # Pipeline de Reconstrucción 3D (SfM offline + Densificación MVS)
38
+
39
+ Pipeline **offline** que reconstruye una escena 3D a partir de un **video
40
+ monocular**: estima la trayectoria de la cámara mediante Structure-from-Motion
41
+ (SfM) incremental, refina con Bundle Adjustment y genera una nube de puntos
42
+ —primero rala (*sparse*) y luego densa (*dense*)—.
43
+
44
+ > **Nota sobre el nombre:** aunque el repo se llama "Template-SLAM", esto es SfM
45
+ > offline + densificación MVS, **no SLAM en tiempo real**. No hay loop-closure ni
46
+ > mapeo online. Ver [CLAUDE.md](CLAUDE.md) para el detalle técnico.
47
+
48
+ ## Características
49
+
50
+ - **3 front-ends de features intercambiables:**
51
+ - `sift` (default) — SIFT + BFMatcher (L2). Solo CPU, sin dependencias pesadas.
52
+ - `orb` — ORB + BFMatcher (Hamming). Más rápido, menos preciso.
53
+ - `spglue` — SuperPoint + **LightGlue** (deep learning, CPU/GPU). Opcional,
54
+ requiere `torch`.
55
+ - **Bundle Adjustment** local (por ventana, durante el tracking) y global.
56
+ - **Densificación MVS-lite** por stereo de dos vistas (StereoSGBM) con fusión
57
+ multi-vista.
58
+ - **Mallado con CGAL** ([cgal_mesh/](cgal_mesh/)) — reconstruye una malla
59
+ triangulada desde la nube densa (Advancing Front o Poisson).
60
+ - **Visor POV interactivo** que proyecta los puntos 3D sobre el video original.
61
+ - **Orquestador único** ([pipeline.py](pipeline.py)) — todo el pipeline en un
62
+ solo comando.
63
+ - **Calibración desde video** ([calibrate.py](calibrate.py)) — estima `K` de tu
64
+ dispositivo a partir de un video de un tablero de ajedrez y crea/actualiza
65
+ `camera.json`.
66
+ - **Paralelización** (`--jobs`) en extracción, matching y densificación.
67
+ - **Reconstrucción por chunks** ([chunked.py](chunked.py)) — para videos largos:
68
+ parte el video en fragmentos solapados, los reconstruye en paralelo y fusiona
69
+ las nubes alineándolas por el solape (similaridad Sim(3)).
70
+
71
+ ## Requisitos
72
+
73
+ - **[uv](https://docs.astral.sh/uv/)** para gestionar el entorno y dependencias.
74
+ - Python ≥ 3.10 (uv lo instala automáticamente según `.python-version`).
75
+ - **Solo para el mallado** (`mesh`): dependencias nativas de CGAL (no las instala
76
+ uv). En macOS: `brew install cgal cmake eigen boost gmp mpfr`. En Debian/Ubuntu:
77
+ `sudo apt install libcgal-dev cmake libeigen3-dev`. El resto del pipeline
78
+ funciona sin ellas.
79
+
80
+ ## Instalación
81
+
82
+ ```bash
83
+ # Dependencias base (front-ends sift / orb):
84
+ uv sync
85
+
86
+ # Opcional: front-end spglue (SuperPoint + LightGlue, instala torch):
87
+ uv sync --extra spglue
88
+ ```
89
+
90
+ `uv` crea el entorno virtual, **instala el paquete `reconstruct3d`** (editable) y
91
+ resuelve todo desde `pyproject.toml`. No hace falta activar nada: usa
92
+ `uv run <comando>`. Queda disponible el CLI instalado `reconstruct3d` (equivalente
93
+ al shim `python pipeline.py`).
94
+
95
+ ## Uso como librería (API Python)
96
+
97
+ El pipeline se puede usar desde código con la clase `Pipeline`:
98
+
99
+ ```python
100
+ from reconstruct3d import Pipeline
101
+
102
+ pipe = Pipeline("outputs/run1", frontend="sift", camera="camera.json", jobs=0)
103
+ pipe.extract("video.mp4", k_skip=15, m_window=4)
104
+ pipe.init()
105
+ pipe.track()
106
+ pipe.bundle_adjust()
107
+ pipe.dense("video.mp4")
108
+ pipe.mesh(method="afront")
109
+ print(pipe.artifacts()) # {'extract': '.../sfm_data.pkl', 'dense': '.../dense_cloud.ply', ...}
110
+ ```
111
+
112
+ O todo de una vez, eligiendo etapas y recibiendo progreso por callback:
113
+
114
+ ```python
115
+ from reconstruct3d import Pipeline
116
+
117
+ def on_event(ev): # ev = {stage, status, message, ...}
118
+ print(ev["stage"], ev["status"])
119
+
120
+ pipe = Pipeline("outputs/run1", on_event=on_event)
121
+ pipe.run("video.mp4",
122
+ stages=["extract", "init", "track", "dense"],
123
+ config={"extract": {"k_skip": 15, "m_window": 4}})
124
+ ```
125
+
126
+ Atajo: `reconstruct3d.run_all(video, out_dir, stages=..., config=...)`.
127
+
128
+ ## Uso rápido (CLI)
129
+
130
+ Coloca tu video en `data/` y ejecuta el pipeline completo:
131
+
132
+ ```bash
133
+ uv run reconstruct3d all data/mi_video.mp4 # o: uv run python pipeline.py all ...
134
+ ```
135
+
136
+ Esto encadena: **extract → init → track → ba → dense → mesh**. Los artefactos
137
+ quedan en `outputs/sift/` (o `outputs/<frontend>/`). El mallado se omite
138
+ automáticamente si CGAL no está instalado (o con `--no-mesh`).
139
+
140
+ Con otro front-end, o saltando etapas:
141
+
142
+ ```bash
143
+ uv run python pipeline.py all data/mi_video.mp4 --frontend spglue
144
+ uv run python pipeline.py all data/mi_video.mp4 --no-ba --no-dense # solo sparse
145
+ uv run python pipeline.py all data/mi_video.mp4 --view # abre el visor al final
146
+ ```
147
+
148
+ ## Cámara / calibración (por dispositivo)
149
+
150
+ La matriz intrínseca `K` **depende del dispositivo con el que grabaste**, así que
151
+ es configurable. Copia [camera.example.json](camera.example.json), ajústalo a tu
152
+ cámara y pásalo en `extract` (o en `all`):
153
+
154
+ ```bash
155
+ uv run python pipeline.py all data/mi_video.mp4 --camera camera.json
156
+ ```
157
+
158
+ La config se **persiste** en `sfm_data.pkl` y `map_state.npy` y se **propaga
159
+ automáticamente** a todas las etapas — solo la indicas una vez. Sin `--camera`,
160
+ se usan los valores por defecto (iPhone @ 540×960).
161
+
162
+ Formato del JSON (atajo `fx/fy/cx/cy`, o matriz `K` completa):
163
+
164
+ ```json
165
+ {
166
+ "fx": 801.25, "fy": 801.25, "cx": 188.67, "cy": 390.22,
167
+ "width": 540, "height": 960,
168
+ "dist_coeffs": [0, 0, 0, 0, 0]
169
+ }
170
+ ```
171
+
172
+ `width`/`height` es la resolución a la que `K` está calibrada: el video se
173
+ redimensiona a ese tamaño antes de extraer features. Si das `fx/fy/cx/cy`, deben
174
+ corresponder a esa resolución.
175
+
176
+ ### Calibrar K automáticamente desde un video
177
+
178
+ Si no conoces `K`, grábala: graba un video moviendo un **tablero de ajedrez**
179
+ frente a la cámara (cubriendo zonas y ángulos) y calibra:
180
+
181
+ ```bash
182
+ # Genera/actualiza camera.json (tablero de 9x6 esquinas internas):
183
+ uv run python pipeline.py calibrate data/calib.mp4 --board 9x6 --square 0.025
184
+ # Revisión manual de cada vista (ventana OpenCV):
185
+ uv run python pipeline.py calibrate data/calib.mp4 --interactive
186
+ ```
187
+
188
+ También puedes calibrar **en el mismo comando** de reconstrucción, o dejar que el
189
+ pipeline lo haga solo:
190
+
191
+ ```bash
192
+ # Calibra y luego reconstruye, en un paso:
193
+ uv run python pipeline.py all data/video.mp4 --calibrate data/calib.mp4
194
+
195
+ # Auto-detección: si no pasas --camera, el pipeline usa ./camera.json si existe,
196
+ # o busca un video con 'calib' en el nombre (en data/calib/, data/ o .) y calibra.
197
+ uv run python pipeline.py all data/video.mp4
198
+ ```
199
+
200
+ Calibrar fija `proc_size` a la resolución nativa del video de calibración, así que
201
+ el punto principal queda centrado y `K` siempre es coherente con la resolución.
202
+
203
+ ## Paralelización (`--jobs`)
204
+
205
+ La extracción de features, el matching por pares y la densificación MVS están
206
+ paralelizados con hilos. Controla los hilos con `--jobs` (`0`=auto=nº de CPUs,
207
+ `1`=secuencial):
208
+
209
+ ```bash
210
+ uv run python pipeline.py extract data/video.mp4 --jobs 8
211
+ uv run python pipeline.py dense data/video.mp4 --jobs 8
212
+ uv run python pipeline.py all data/video.mp4 --jobs 8
213
+ ```
214
+
215
+ Notas: los detectores de OpenCV no son thread-safe compartidos, así que cada hilo
216
+ usa su propia instancia (resultados **idénticos** al modo secuencial). Con
217
+ `--frontend spglue` el paralelismo se fuerza a 1 hilo (torch ya paraleliza
218
+ internamente y su modelo no es thread-safe).
219
+
220
+ ## Videos largos: reconstrucción por chunks
221
+
222
+ Para videos largos, reconstruir todo de una vez es lento y acumula deriva. El modo
223
+ `chunked` parte el video en fragmentos **solapados**, reconstruye cada uno de forma
224
+ **independiente y en paralelo** (procesos), y fusiona las sub-nubes alineándolas
225
+ por los frames del solape (similaridad Sim(3) vía Umeyama sobre los centros de
226
+ cámara compartidos):
227
+
228
+ ```bash
229
+ uv run python pipeline.py chunked data/video.mp4 \
230
+ --chunk 80 --overlap 20 --chunk-jobs 4
231
+ ```
232
+
233
+ - `--chunk` / `--overlap`: tamaño y solape del fragmento, en frames muestreados.
234
+ El solape debe ser suficiente para alinear (≥4 frames; por defecto 20).
235
+ - `--chunk-jobs`: cuántos chunks se reconstruyen en paralelo (procesos).
236
+ - `--inner-jobs`: hilos de extracción dentro de cada chunk (default 1, para no
237
+ saturar al correr varios chunks a la vez).
238
+
239
+ Salida en `outputs/<frontend>/`: `merged_cloud.ply` (nube global) y
240
+ `merged_state.npy` (poses + puntos en el marco global, copiado también como
241
+ `map_state.npy` para poder lanzar `dense`/`view` sobre el resultado fusionado).
242
+
243
+ ## Mallado de la nube (CGAL)
244
+
245
+ Convierte la nube densa en una **malla triangulada** con CGAL. Requiere las
246
+ dependencias nativas (ver *Requisitos*); el binario C++ se **compila solo** la
247
+ primera vez que se ejecuta.
248
+
249
+ ```bash
250
+ uv run python pipeline.py mesh # usa outputs/sift/dense_cloud.ply
251
+ uv run python pipeline.py mesh outputs/sift/dense_cloud.ply # ruta explícita a la nube
252
+ uv run python pipeline.py mesh ruta/a/nube.ply --method poisson --smooth 24
253
+ ```
254
+
255
+ Puedes indicar la nube de entrada como **argumento posicional** (o con `--input`);
256
+ si no pasas `--out`, el `mesh.ply` se escribe en la carpeta de esa nube.
257
+
258
+ Dos métodos:
259
+
260
+ - **`afront`** (Advancing Front, default) — **interpola** los puntos de entrada,
261
+ conserva el color y respeta bordes abiertos. Ideal para superficies vistas de un
262
+ lado (fachadas). Fiel a la nube.
263
+ - **`poisson`** (Poisson screened) — superficie **suave y cerrada**, tolera mejor
264
+ el ruido pero puede "inflar" zonas abiertas. Estima normales y transfiere el
265
+ color por vecino más cercano.
266
+
267
+ ### Mejorar la calidad (la nube tiene ruido)
268
+
269
+ Advancing Front **interpola** los puntos, así que el ruido se vuelve picos
270
+ ("grumoso"). Para una malla más limpia hay tres palancas, aplicadas por defecto y
271
+ ajustables:
272
+
273
+ - **Limpiar la nube antes de mallar**: `--outlier-pct P` (elimina % de outliers),
274
+ `--simplify CELL` (rejilla; `0`=auto~2×spacing, coarsea→suaviza y acelera;
275
+ `<0`=sin simplificar para máximo detalle), `--smooth N` (suavizado jet de los
276
+ puntos con N vecinos).
277
+ - **Post-procesar la malla** (activo por defecto): `--mesh-smooth ITERS` (suavizado
278
+ tangencial que respeta bordes, default 2) y `--min-component FRAC` (elimina
279
+ componentes con menos de `FRAC×caras`, p.ej. islas de ruido flotantes,
280
+ default 0.002).
281
+ - **Cambiar de método**: `--method poisson` produce una superficie **suave y
282
+ cerrada** que tolera mucho mejor el ruido (a costa de "inflar" bordes abiertos).
283
+
284
+ ```bash
285
+ # Más limpio (afront + suavizado fuerte + quitar islas):
286
+ uv run python pipeline.py mesh --mesh-smooth 5 --min-component 0.01 --smooth 12
287
+ # Superficie suave (Poisson):
288
+ uv run python pipeline.py mesh --method poisson --smooth 12
289
+ # Máximo detalle (sin simplificar ni suavizar):
290
+ uv run python pipeline.py mesh --simplify -1 --mesh-smooth 0 --min-component 0
291
+ ```
292
+
293
+ La salida es `mesh.ply`, abrible en MeshLab/CloudCompare o cualquier visor de PLY.
294
+
295
+ ## Uso por etapas
296
+
297
+ Las etapas comparten el mismo directorio de salida. Útil para iterar sobre una
298
+ etapa sin recalcular las anteriores:
299
+
300
+ | Etapa | Comando | Produce |
301
+ |---|---|---|
302
+ | 1. Extracción | `uv run python pipeline.py extract data/v.mp4` | `sfm_data.pkl` |
303
+ | 2. Inicialización | `uv run python pipeline.py init` | `map_state.npy`, `init_cloud.ply` |
304
+ | 3. Tracking (sparse) | `uv run python pipeline.py track` | `tracked_cloud.ply` |
305
+ | 4. Bundle Adjustment | `uv run python pipeline.py ba` | `map_state.npy` (refinado) |
306
+ | 5. Densificación | `uv run python pipeline.py dense data/v.mp4` | `dense_cloud.ply` |
307
+ | 6. Mallado (CGAL) | `uv run python pipeline.py mesh` | `mesh.ply` |
308
+ | 7. Visor | `uv run python pipeline.py view data/v.mp4` | (interactivo) |
309
+
310
+ Cada subcomando expone sus parámetros; consúltalos con `--help`:
311
+
312
+ ```bash
313
+ uv run python pipeline.py extract --help
314
+ uv run python pipeline.py track --help
315
+ ```
316
+
317
+ Parámetros frecuentes:
318
+
319
+ - `extract --k-skip N` — procesa 1 de cada N frames (default 5).
320
+ - `extract --start-seconds S` — salta un arranque malo (rotación casi pura).
321
+ - `track --min-angle G` — ángulo mínimo de triangulación (descarta ruido de escala).
322
+ - `dense --min-views N` — conserva solo puntos confirmados por ≥N pares.
323
+
324
+ ## Resultados
325
+
326
+ Las nubes `.ply` se abren en **MeshLab** o **CloudCompare**. El visor interactivo
327
+ proyecta los puntos sobre el video:
328
+
329
+ - Slider **Frame** — navega en el tiempo.
330
+ - Slider **Fondo %** — opacidad del video (0 = fondo negro, 100 = video normal).
331
+ - `q` o `ESC` — cerrar.
332
+
333
+ ## Demo web (API + frontend)
334
+
335
+ Una demo de la librería: backend FastAPI que expone el pipeline por HTTP +
336
+ frontend Vite/React con **visor 3D** (Three.js) para subir un video, elegir las
337
+ etapas, ver el progreso y explorar la nube/malla resultante en el navegador.
338
+
339
+ ```bash
340
+ # 1) Backend (instala FastAPI con el extra `api`):
341
+ uv sync --extra api
342
+ uv run uvicorn backend.app:app --reload --port 8000
343
+
344
+ # 2) Frontend (en otra terminal):
345
+ cd frontend
346
+ npm install
347
+ npm run dev # http://localhost:5173 (proxy /api -> :8000)
348
+ ```
349
+
350
+ Abre http://localhost:5173, sube un video, marca las etapas y pulsa
351
+ **Reconstruir**; al terminar, haz clic en un artefacto para verlo en 3D.
352
+
353
+ Endpoints principales del backend: `POST /api/jobs` (video + config),
354
+ `GET /api/jobs/{id}` (estado/progreso/eventos), `GET /api/jobs/{id}/artifacts/{name}`.
355
+
356
+ ## Estructura del proyecto
357
+
358
+ ```
359
+ reconstruct3d/ Paquete de la librería (instalable)
360
+ api.py API de alto nivel (clase Pipeline)
361
+ cli.py Orquestador CLI (subcomandos)
362
+ core.py Cámara, features, front-ends, base de datos SfM
363
+ init_sfm.py Par semilla + triangulación inicial
364
+ track_sfm.py Registro incremental PnP + BA local
365
+ bundle_adjust.py BA local (ventana) y global + fusión de puntos
366
+ dense_mvs.py Densificación stereo multi-vista
367
+ mesh.py Wrapper del mallado CGAL (compila y llama al binario)
368
+ calibrate.py Calibración de K desde un video de tablero
369
+ chunked.py Reconstrucción por chunks con solape + fusión
370
+ viewer.py Visor POV interactivo (OpenCV)
371
+ cgal_mesh/ Programa C++ CGAL (mesh_reconstruct.cpp + CMakeLists)
372
+ pipeline.py Shim de compatibilidad -> reconstruct3d.cli
373
+ backend/ Demo: API FastAPI (app.py)
374
+ frontend/ Demo: Vite + React + Three.js (visor 3D)
375
+ camera.example.json Plantilla de intrínsecos por dispositivo
376
+ pyproject.toml Paquete + dependencias (fuente de verdad)
377
+ data/ Videos de entrada (no versionados)
378
+ outputs/ Artefactos regenerables (no versionados)
379
+ ```
380
+
381
+ ## Publicar en PyPI
382
+
383
+ El paquete está listo para publicarse (`twine check` PASSED; nombre `reconstruct3d`
384
+ libre). Pasos:
385
+
386
+ ```bash
387
+ uv build # genera dist/*.whl y dist/*.tar.gz
388
+ uv run --with twine twine check dist/*
389
+
390
+ # Ensayo en TestPyPI (recomendado):
391
+ uv publish --publish-url https://test.pypi.org/legacy/ --token <TEST_PYPI_TOKEN>
392
+
393
+ # Publicación real:
394
+ uv publish --token <PYPI_TOKEN>
395
+ ```
396
+
397
+ Notas para quien instale desde PyPI:
398
+
399
+ - `pip install reconstruct3d` trae los front-ends **SIFT/ORB** (sin torch).
400
+ - El front-end **spglue** (SuperPoint+LightGlue) requiere instalar LightGlue a
401
+ mano (no está en PyPI):
402
+ `pip install "reconstruct3d[spglue]"` y luego
403
+ `pip install "lightglue @ git+https://github.com/cvg/LightGlue.git"`.
404
+ - El paso **`mesh`** necesita CGAL nativo (CGAL + cmake + compilador); es opcional
405
+ y se compila bajo demanda. El resto del pipeline funciona sin él.
406
+
407
+ ## Notas técnicas
408
+
409
+ - **Reset:** si el tracking se estanca, vuelve a correr `init` antes de reintentar.
410
+ - **Calibración:** los intrínsecos por defecto son de un iPhone @ 540×960. Para
411
+ otro dispositivo, pasa `--camera tu_camara.json` (ver sección *Cámara*). El
412
+ video se redimensiona a la resolución de calibración antes de extraer.
413
+ - **`req.txt`** queda como referencia histórica; la gestión real de dependencias
414
+ es `pyproject.toml` + `uv`.
415
+
416
+ Para contexto de arquitectura, convenciones y *gotchas*, ver **[CLAUDE.md](CLAUDE.md)**.
@@ -0,0 +1,19 @@
1
+ reconstruct3d/__init__.py,sha256=_MTKAhDNA4uvxu-srxMYfLgSgDgM5frCci1SMfGSHEY,685
2
+ reconstruct3d/api.py,sha256=v57OzbwK0t1lGz1SDWNj2_m1AgsAs9iLbEjlr7OdM7o,9406
3
+ reconstruct3d/bundle_adjust.py,sha256=7IW4lx7PhsLXL6kh_Ibq2oyihdLQ-eBZsbzDlS6O04A,14831
4
+ reconstruct3d/calibrate.py,sha256=lG9xk2bEF05PCaT1flH8w5NGQqoUBCTLtysNyX7rUWE,8586
5
+ reconstruct3d/chunked.py,sha256=HuSRF49vpZ2KOoj4S0xQ0mwLXvjEedsdpVR7yi-b7rI,15672
6
+ reconstruct3d/cli.py,sha256=zMxcFe5NwpY5tZMEdBmXJXyPHgU4dGiLGOfzJMEo4Ag,21227
7
+ reconstruct3d/core.py,sha256=0aFS1SwZ6zBP67kBABFKsXLqnt9HyBEh2GuK5afz50w,21625
8
+ reconstruct3d/dense_mvs.py,sha256=w9K9GxDqcykFwjEnNotvNlVJHccfSDOLlzsXr8kpUzU,11110
9
+ reconstruct3d/init_sfm.py,sha256=q_9d-QRhtuxMGtz-8K_mnHN0Bj1_GIEmr5v54YY5UC4,6225
10
+ reconstruct3d/mesh.py,sha256=UvdrXA1x7xeeHcMnJFvSdFPr-SBhui8mbfwlByuknUg,5031
11
+ reconstruct3d/track_sfm.py,sha256=Z-8OtycWBzmHGw_HAmZyIZUeltAZglMxKoI9JhrbExM,12004
12
+ reconstruct3d/viewer.py,sha256=Zx09CT1R1dNUZ9sOqJjJTvu2CmFuJa5aE5RiyCtKzzY,4223
13
+ reconstruct3d/cgal_mesh/CMakeLists.txt,sha256=L187LXfy1269jNi2OCW3m8elHTsXvbTPzz66RQJ5qKk,696
14
+ reconstruct3d/cgal_mesh/mesh_reconstruct.cpp,sha256=AyrjBmKcvz61pzIyUY4Li-kj52MOaD-kALpraqKfsjI,13491
15
+ reconstruct3d-0.1.0.dist-info/METADATA,sha256=Kuq_43qPu1gFCgl323wWPGCojwajTGtYKk6NBjx7rfs,17515
16
+ reconstruct3d-0.1.0.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
17
+ reconstruct3d-0.1.0.dist-info/entry_points.txt,sha256=2RatR0ezPmG_FFZYsXGrzm2KdCfUW5zU11YDZtNyRkY,57
18
+ reconstruct3d-0.1.0.dist-info/licenses/LICENSE,sha256=M5sWK_Vw7QdMjgdL6cyM2JeVzzIp3Q8d1l73Fa8e7a4,1068
19
+ reconstruct3d-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.30.1
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ reconstruct3d = reconstruct3d.cli:main
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 BlackMonkcr
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.