wildflow-splat 0.1.3__tar.gz → 0.1.4__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.
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/Cargo.lock +32 -32
- wildflow_splat-0.1.4/PKG-INFO +74 -0
- wildflow_splat-0.1.4/README.md +43 -0
- wildflow_splat-0.1.4/examples/patches_example.py +140 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/meta-package/pyproject.toml +2 -2
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/native/lib.rs +6 -0
- wildflow_splat-0.1.4/native/patches.rs +562 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/pyproject.toml +1 -1
- wildflow_splat-0.1.4/requirements-dev.txt +2 -0
- wildflow_splat-0.1.4/requirements.txt +3 -0
- wildflow_splat-0.1.4/tests/__init__.py +1 -0
- wildflow_splat-0.1.4/tests/test_patches.py +301 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/wildflow/__init__.py +1 -1
- wildflow_splat-0.1.4/wildflow/splat/__init__.py +24 -0
- wildflow_splat-0.1.4/wildflow/splat/patches.py +65 -0
- wildflow_splat-0.1.3/PKG-INFO +0 -170
- wildflow_splat-0.1.3/README.md +0 -139
- wildflow_splat-0.1.3/configs/q5.yaml +0 -21
- wildflow_splat-0.1.3/requirements-dev.txt +0 -1
- wildflow_splat-0.1.3/setup.cfg +0 -2
- wildflow_splat-0.1.3/wildflow/splat/__init__.py +0 -9
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/.gitattributes +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/.github/workflows/build-wheels.yml +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/.github/workflows/publish.yml +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/.gitignore +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/Cargo.toml +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/LICENSE +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/images/wildflow-3dgs-wf.svg +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/meta-package/.gitignore +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/meta-package/README.md +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/meta-package/wildflow/__init__.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/native/split.rs +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/clean.go +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/cleanup_splats.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/copy_cell.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/cell.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/colmap_reader.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/crop_colmap.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/grid.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/ply_reader.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/processor.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/types.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/core/visualizer.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/export_cell.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/export_cells.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/plan.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/plot_colmap.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/plot_ply.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/ply_to_colmap_bin.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4/refurbish}/run.py +0 -0
- {wildflow_splat-0.1.3 → wildflow_splat-0.1.4}/wildflow/splat/split.py +0 -0
@@ -4,21 +4,21 @@ version = 4
|
|
4
4
|
|
5
5
|
[[package]]
|
6
6
|
name = "autocfg"
|
7
|
-
version = "1.
|
7
|
+
version = "1.5.0"
|
8
8
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
9
|
-
checksum = "
|
9
|
+
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
10
10
|
|
11
11
|
[[package]]
|
12
12
|
name = "bumpalo"
|
13
|
-
version = "3.
|
13
|
+
version = "3.19.0"
|
14
14
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
15
|
-
checksum = "
|
15
|
+
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
|
16
16
|
|
17
17
|
[[package]]
|
18
18
|
name = "cfg-if"
|
19
|
-
version = "1.0.
|
19
|
+
version = "1.0.1"
|
20
20
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
21
|
-
checksum = "
|
21
|
+
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
|
22
22
|
|
23
23
|
[[package]]
|
24
24
|
name = "console"
|
@@ -93,9 +93,9 @@ dependencies = [
|
|
93
93
|
|
94
94
|
[[package]]
|
95
95
|
name = "libc"
|
96
|
-
version = "0.2.
|
96
|
+
version = "0.2.174"
|
97
97
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
98
|
-
checksum = "
|
98
|
+
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
|
99
99
|
|
100
100
|
[[package]]
|
101
101
|
name = "log"
|
@@ -105,9 +105,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
|
|
105
105
|
|
106
106
|
[[package]]
|
107
107
|
name = "memchr"
|
108
|
-
version = "2.7.
|
108
|
+
version = "2.7.5"
|
109
109
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
110
|
-
checksum = "
|
110
|
+
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
|
111
111
|
|
112
112
|
[[package]]
|
113
113
|
name = "memoffset"
|
@@ -132,9 +132,9 @@ checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|
132
132
|
|
133
133
|
[[package]]
|
134
134
|
name = "portable-atomic"
|
135
|
-
version = "1.11.
|
135
|
+
version = "1.11.1"
|
136
136
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
137
|
-
checksum = "
|
137
|
+
checksum = "f84267b20a16ea918e43c6a88433c2d54fa145c92a811b5b047ccbe153674483"
|
138
138
|
|
139
139
|
[[package]]
|
140
140
|
name = "ppv-lite86"
|
@@ -156,9 +156,9 @@ dependencies = [
|
|
156
156
|
|
157
157
|
[[package]]
|
158
158
|
name = "pyo3"
|
159
|
-
version = "0.25.
|
159
|
+
version = "0.25.1"
|
160
160
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
161
|
-
checksum = "
|
161
|
+
checksum = "8970a78afe0628a3e3430376fc5fd76b6b45c4d43360ffd6cdd40bdde72b682a"
|
162
162
|
dependencies = [
|
163
163
|
"indoc",
|
164
164
|
"libc",
|
@@ -173,9 +173,9 @@ dependencies = [
|
|
173
173
|
|
174
174
|
[[package]]
|
175
175
|
name = "pyo3-build-config"
|
176
|
-
version = "0.25.
|
176
|
+
version = "0.25.1"
|
177
177
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
178
|
-
checksum = "
|
178
|
+
checksum = "458eb0c55e7ece017adeba38f2248ff3ac615e53660d7c71a238d7d2a01c7598"
|
179
179
|
dependencies = [
|
180
180
|
"once_cell",
|
181
181
|
"target-lexicon",
|
@@ -183,9 +183,9 @@ dependencies = [
|
|
183
183
|
|
184
184
|
[[package]]
|
185
185
|
name = "pyo3-ffi"
|
186
|
-
version = "0.25.
|
186
|
+
version = "0.25.1"
|
187
187
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
188
|
-
checksum = "
|
188
|
+
checksum = "7114fe5457c61b276ab77c5055f206295b812608083644a5c5b2640c3102565c"
|
189
189
|
dependencies = [
|
190
190
|
"libc",
|
191
191
|
"pyo3-build-config",
|
@@ -193,9 +193,9 @@ dependencies = [
|
|
193
193
|
|
194
194
|
[[package]]
|
195
195
|
name = "pyo3-macros"
|
196
|
-
version = "0.25.
|
196
|
+
version = "0.25.1"
|
197
197
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
198
|
-
checksum = "
|
198
|
+
checksum = "a8725c0a622b374d6cb051d11a0983786448f7785336139c3c94f5aa6bef7e50"
|
199
199
|
dependencies = [
|
200
200
|
"proc-macro2",
|
201
201
|
"pyo3-macros-backend",
|
@@ -205,9 +205,9 @@ dependencies = [
|
|
205
205
|
|
206
206
|
[[package]]
|
207
207
|
name = "pyo3-macros-backend"
|
208
|
-
version = "0.25.
|
208
|
+
version = "0.25.1"
|
209
209
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
210
|
-
checksum = "
|
210
|
+
checksum = "4109984c22491085343c05b0dbc54ddc405c3cf7b4374fc533f5c3313a572ccc"
|
211
211
|
dependencies = [
|
212
212
|
"heck",
|
213
213
|
"proc-macro2",
|
@@ -295,9 +295,9 @@ dependencies = [
|
|
295
295
|
|
296
296
|
[[package]]
|
297
297
|
name = "syn"
|
298
|
-
version = "2.0.
|
298
|
+
version = "2.0.104"
|
299
299
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
300
|
-
checksum = "
|
300
|
+
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
|
301
301
|
dependencies = [
|
302
302
|
"proc-macro2",
|
303
303
|
"quote",
|
@@ -318,9 +318,9 @@ checksum = "5a5f39404a5da50712a4c1eecf25e90dd62b613502b7e925fd4e4d19b5c96512"
|
|
318
318
|
|
319
319
|
[[package]]
|
320
320
|
name = "unicode-width"
|
321
|
-
version = "0.2.
|
321
|
+
version = "0.2.1"
|
322
322
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
323
|
-
checksum = "
|
323
|
+
checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c"
|
324
324
|
|
325
325
|
[[package]]
|
326
326
|
name = "unindent"
|
@@ -330,9 +330,9 @@ checksum = "7264e107f553ccae879d21fbea1d6724ac785e8c3bfc762137959b5802826ef3"
|
|
330
330
|
|
331
331
|
[[package]]
|
332
332
|
name = "wasi"
|
333
|
-
version = "0.11.
|
333
|
+
version = "0.11.1+wasi-snapshot-preview1"
|
334
334
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
335
|
-
checksum = "
|
335
|
+
checksum = "ccf3ec651a847eb01de73ccad15eb7d99f80485de043efb2f370cd654f4ea44b"
|
336
336
|
|
337
337
|
[[package]]
|
338
338
|
name = "wasm-bindgen"
|
@@ -487,18 +487,18 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
|
487
487
|
|
488
488
|
[[package]]
|
489
489
|
name = "zerocopy"
|
490
|
-
version = "0.8.
|
490
|
+
version = "0.8.26"
|
491
491
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
492
|
-
checksum = "
|
492
|
+
checksum = "1039dd0d3c310cf05de012d8a39ff557cb0d23087fd44cad61df08fc31907a2f"
|
493
493
|
dependencies = [
|
494
494
|
"zerocopy-derive",
|
495
495
|
]
|
496
496
|
|
497
497
|
[[package]]
|
498
498
|
name = "zerocopy-derive"
|
499
|
-
version = "0.8.
|
499
|
+
version = "0.8.26"
|
500
500
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
501
|
-
checksum = "
|
501
|
+
checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181"
|
502
502
|
dependencies = [
|
503
503
|
"proc-macro2",
|
504
504
|
"quote",
|
@@ -0,0 +1,74 @@
|
|
1
|
+
Metadata-Version: 2.4
|
2
|
+
Name: wildflow-splat
|
3
|
+
Version: 0.1.4
|
4
|
+
Classifier: Development Status :: 4 - Beta
|
5
|
+
Classifier: Intended Audience :: Developers
|
6
|
+
Classifier: Intended Audience :: Science/Research
|
7
|
+
Classifier: License :: OSI Approved :: MIT License
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
9
|
+
Classifier: Programming Language :: Python :: 3.8
|
10
|
+
Classifier: Programming Language :: Python :: 3.9
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
14
|
+
Classifier: Programming Language :: Rust
|
15
|
+
Classifier: Topic :: Scientific/Engineering
|
16
|
+
Classifier: Topic :: Multimedia :: Graphics :: 3D Modeling
|
17
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
18
|
+
Requires-Dist: maturin>=1.0 ; extra == 'dev'
|
19
|
+
Requires-Dist: pytest>=7.0 ; extra == 'dev'
|
20
|
+
Provides-Extra: dev
|
21
|
+
License-File: LICENSE
|
22
|
+
Summary: Fast PLY point cloud processing for 3D Gaussian splatting workflows
|
23
|
+
Keywords: ply,point-cloud,3d-gaussian-splatting,colmap,photogrammetry,computer-vision
|
24
|
+
Author-email: Wildflow AI <info@wildflow.ai>
|
25
|
+
License: MIT
|
26
|
+
Requires-Python: >=3.8
|
27
|
+
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
|
28
|
+
Project-URL: repository, https://github.com/wildflowai/wildflow-splat
|
29
|
+
Project-URL: documentation, https://docs.wildflow.ai
|
30
|
+
|
31
|
+
Super hacky library to work with coral reef splats.
|
32
|
+
|
33
|
+
You can swim with a few GoPros around a reef (e.g. [wildflow.ai/protocol](https://wildflow.ai/protocol)) and then turn the footage into 3D models (e.g. [wildflow.ai/demo](https://wildflow.ai/demo)) to track changes over time, run different analysis on top of it, and ultimately see which conservation/restoration methods work best.
|
34
|
+
|
35
|
+
This is a bunch of primitives to process the data.
|
36
|
+
|
37
|
+
# Usage
|
38
|
+
Install with
|
39
|
+
```
|
40
|
+
pip install wildflow
|
41
|
+
```
|
42
|
+
So you can play with it from python:
|
43
|
+
```py
|
44
|
+
from wildflow import splat
|
45
|
+
splat.split(...)
|
46
|
+
```
|
47
|
+
# Workflow
|
48
|
+
|
49
|
+
## SfM workflow
|
50
|
+
Turns images from cameras 3D point cloud and
|
51
|
+
|
52
|
+

|
53
|
+
|
54
|
+
# Local Development
|
55
|
+
|
56
|
+
This library uses Rust extensions built with Maturin. To set up locally:
|
57
|
+
|
58
|
+
```bash
|
59
|
+
# Create virtual environment
|
60
|
+
python3 -m venv venv
|
61
|
+
source venv/bin/activate
|
62
|
+
|
63
|
+
# Install Rust (if not already installed)
|
64
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
65
|
+
source "$HOME/.cargo/env"
|
66
|
+
|
67
|
+
# Install dependencies and build
|
68
|
+
pip install maturin
|
69
|
+
pip install -r requirements.txt
|
70
|
+
maturin develop
|
71
|
+
```
|
72
|
+
|
73
|
+
After making changes to Rust code, rebuild with `maturin develop`.
|
74
|
+
|
@@ -0,0 +1,43 @@
|
|
1
|
+
Super hacky library to work with coral reef splats.
|
2
|
+
|
3
|
+
You can swim with a few GoPros around a reef (e.g. [wildflow.ai/protocol](https://wildflow.ai/protocol)) and then turn the footage into 3D models (e.g. [wildflow.ai/demo](https://wildflow.ai/demo)) to track changes over time, run different analysis on top of it, and ultimately see which conservation/restoration methods work best.
|
4
|
+
|
5
|
+
This is a bunch of primitives to process the data.
|
6
|
+
|
7
|
+
# Usage
|
8
|
+
Install with
|
9
|
+
```
|
10
|
+
pip install wildflow
|
11
|
+
```
|
12
|
+
So you can play with it from python:
|
13
|
+
```py
|
14
|
+
from wildflow import splat
|
15
|
+
splat.split(...)
|
16
|
+
```
|
17
|
+
# Workflow
|
18
|
+
|
19
|
+
## SfM workflow
|
20
|
+
Turns images from cameras 3D point cloud and
|
21
|
+
|
22
|
+

|
23
|
+
|
24
|
+
# Local Development
|
25
|
+
|
26
|
+
This library uses Rust extensions built with Maturin. To set up locally:
|
27
|
+
|
28
|
+
```bash
|
29
|
+
# Create virtual environment
|
30
|
+
python3 -m venv venv
|
31
|
+
source venv/bin/activate
|
32
|
+
|
33
|
+
# Install Rust (if not already installed)
|
34
|
+
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
|
35
|
+
source "$HOME/.cargo/env"
|
36
|
+
|
37
|
+
# Install dependencies and build
|
38
|
+
pip install maturin
|
39
|
+
pip install -r requirements.txt
|
40
|
+
maturin develop
|
41
|
+
```
|
42
|
+
|
43
|
+
After making changes to Rust code, rebuild with `maturin develop`.
|
@@ -0,0 +1,140 @@
|
|
1
|
+
"""
|
2
|
+
Example usage of wildflow.splat.patches library for COLMAP camera partitioning.
|
3
|
+
Interactive sliders allow you to explore how different parameters affect the partitioning.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import pycolmap
|
7
|
+
import matplotlib.pyplot as plt
|
8
|
+
import matplotlib.patches as patches
|
9
|
+
from matplotlib.widgets import Slider
|
10
|
+
import math
|
11
|
+
from wildflow.splat import patches as splat_patches, BoundingBox
|
12
|
+
|
13
|
+
# Constants
|
14
|
+
COLMAP_FOLDER = "/Users/nsv/corals/soneva/0/"
|
15
|
+
MAX_CAMERAS = 50
|
16
|
+
BUFFER_METERS = 0.0
|
17
|
+
TARGET_BINS = 100
|
18
|
+
|
19
|
+
def rotate30(cameras: list[tuple[float, float]]) -> list[tuple[float, float]]:
|
20
|
+
"""Rotate camera positions by 30 degrees counter-clockwise."""
|
21
|
+
angle_rad = math.radians(30)
|
22
|
+
cos_angle = math.cos(angle_rad)
|
23
|
+
sin_angle = math.sin(angle_rad)
|
24
|
+
|
25
|
+
rotated = []
|
26
|
+
for x, y in cameras:
|
27
|
+
x_rot = x * cos_angle - y * sin_angle
|
28
|
+
y_rot = x * sin_angle + y * cos_angle
|
29
|
+
rotated.append((x_rot, y_rot))
|
30
|
+
|
31
|
+
return rotated
|
32
|
+
|
33
|
+
def create_interactive_plot(cameras: list[tuple[float, float]]) -> None:
|
34
|
+
"""Create interactive plot with sliders for parameter adjustment."""
|
35
|
+
# Create figure with space for sliders at bottom (smaller to fit on screen)
|
36
|
+
fig = plt.figure(figsize=(12, 9))
|
37
|
+
|
38
|
+
# Main plot takes up most of the space
|
39
|
+
ax_main = plt.axes((0.1, 0.3, 0.8, 0.6))
|
40
|
+
|
41
|
+
# Create slider axes with proper spacing
|
42
|
+
ax_max_cameras = plt.axes((0.2, 0.2, 0.6, 0.03))
|
43
|
+
ax_buffer = plt.axes((0.2, 0.15, 0.6, 0.03))
|
44
|
+
ax_target_bins = plt.axes((0.2, 0.1, 0.6, 0.03))
|
45
|
+
|
46
|
+
# Create sliders with nice snapping values
|
47
|
+
slider_max_cameras = Slider(ax_max_cameras, 'Max Cameras', 1, 2000, valinit=MAX_CAMERAS, valfmt='%d')
|
48
|
+
# Buffer slider with 100 beautiful steps (0.02 increments)
|
49
|
+
slider_buffer = Slider(ax_buffer, 'Buffer (m)', 0.0, 2.0, valinit=BUFFER_METERS, valfmt='%.2f',
|
50
|
+
valstep=0.02)
|
51
|
+
slider_target_bins = Slider(ax_target_bins, 'Target Bins', 10, 300, valinit=TARGET_BINS, valfmt='%d')
|
52
|
+
|
53
|
+
def update_plot(val=None):
|
54
|
+
"""Update the plot when sliders change."""
|
55
|
+
# Clear the main plot
|
56
|
+
ax_main.clear()
|
57
|
+
|
58
|
+
# Get current slider values
|
59
|
+
max_cameras = int(slider_max_cameras.val)
|
60
|
+
buffer_meters = slider_buffer.val
|
61
|
+
target_bins = int(slider_target_bins.val)
|
62
|
+
|
63
|
+
# Run partitioning with current parameters
|
64
|
+
try:
|
65
|
+
bboxes = splat_patches(
|
66
|
+
cameras,
|
67
|
+
max_cameras=max_cameras,
|
68
|
+
buffer_meters=buffer_meters,
|
69
|
+
target_bins=target_bins
|
70
|
+
)
|
71
|
+
|
72
|
+
# Plot camera positions
|
73
|
+
x_coords = [pos[0] for pos in cameras]
|
74
|
+
y_coords = [pos[1] for pos in cameras]
|
75
|
+
ax_main.scatter(x_coords, y_coords, c='red', s=20, alpha=0.7,
|
76
|
+
edgecolors='black', linewidth=0.3, zorder=2)
|
77
|
+
|
78
|
+
# Draw bounding boxes
|
79
|
+
for i, bbox in enumerate(bboxes):
|
80
|
+
rect = patches.Rectangle(
|
81
|
+
(bbox.min_x, bbox.min_y), bbox.width, bbox.height,
|
82
|
+
linewidth=2, edgecolor='blue', facecolor='lightblue', alpha=0.3, zorder=1
|
83
|
+
)
|
84
|
+
ax_main.add_patch(rect)
|
85
|
+
|
86
|
+
# Add box number
|
87
|
+
center_x = bbox.min_x + bbox.width / 2
|
88
|
+
center_y = bbox.min_y + bbox.height / 2
|
89
|
+
ax_main.text(center_x, center_y, str(i+1),
|
90
|
+
horizontalalignment='center', verticalalignment='center',
|
91
|
+
fontsize=12, color='blue', fontweight='bold', zorder=3,
|
92
|
+
bbox=dict(boxstyle="round,pad=0.3", facecolor='white', alpha=0.8))
|
93
|
+
|
94
|
+
# Update title with current parameters
|
95
|
+
ax_main.set_title(f'Camera Partitioning: {len(bboxes)} patches '
|
96
|
+
f'(max_cameras={max_cameras}, buffer={buffer_meters:.2f}m, bins={target_bins})')
|
97
|
+
|
98
|
+
except Exception as e:
|
99
|
+
# Show error message if partitioning fails
|
100
|
+
ax_main.text(0.5, 0.5, f'Error: {str(e)}',
|
101
|
+
transform=ax_main.transAxes, ha='center', va='center',
|
102
|
+
fontsize=14, color='red', bbox=dict(boxstyle="round", facecolor='yellow', alpha=0.8))
|
103
|
+
ax_main.set_title('Partitioning Failed - Try Different Parameters')
|
104
|
+
|
105
|
+
ax_main.set_xlabel('X Position')
|
106
|
+
ax_main.set_ylabel('Y Position')
|
107
|
+
ax_main.grid(True, alpha=0.3)
|
108
|
+
ax_main.set_aspect('equal')
|
109
|
+
|
110
|
+
# Redraw
|
111
|
+
fig.canvas.draw()
|
112
|
+
|
113
|
+
# Connect sliders to update function
|
114
|
+
slider_max_cameras.on_changed(update_plot)
|
115
|
+
slider_buffer.on_changed(update_plot)
|
116
|
+
slider_target_bins.on_changed(update_plot)
|
117
|
+
|
118
|
+
# Initial plot
|
119
|
+
update_plot()
|
120
|
+
|
121
|
+
plt.show()
|
122
|
+
|
123
|
+
def main():
|
124
|
+
# Load camera positions using the exact pattern from docstring
|
125
|
+
print("Loading camera positions...")
|
126
|
+
model = pycolmap.Reconstruction(COLMAP_FOLDER)
|
127
|
+
cameras = [(img.projection_center()[0], img.projection_center()[1])
|
128
|
+
for img in model.images.values()]
|
129
|
+
print(f"Loaded {len(cameras)} camera positions")
|
130
|
+
|
131
|
+
# Rotate cameras (can be commented out easily)
|
132
|
+
cameras = rotate30(cameras)
|
133
|
+
|
134
|
+
# Create interactive visualization
|
135
|
+
print("Creating interactive visualization...")
|
136
|
+
print("Use the sliders to adjust parameters and see how they affect the partitioning!")
|
137
|
+
create_interactive_plot(cameras)
|
138
|
+
|
139
|
+
if __name__ == "__main__":
|
140
|
+
main()
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "wildflow"
|
7
|
-
version = "0.1.
|
7
|
+
version = "0.1.4"
|
8
8
|
description = "Modeling natural ecosystems"
|
9
9
|
readme = "README.md"
|
10
10
|
requires-python = ">=3.8"
|
@@ -28,7 +28,7 @@ classifiers = [
|
|
28
28
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
29
29
|
]
|
30
30
|
dependencies = [
|
31
|
-
"wildflow-splat>=0.1.
|
31
|
+
"wildflow-splat>=0.1.4",
|
32
32
|
]
|
33
33
|
|
34
34
|
[project.urls]
|
@@ -1,6 +1,7 @@
|
|
1
1
|
use pyo3::prelude::*;
|
2
2
|
|
3
3
|
mod split;
|
4
|
+
mod patches;
|
4
5
|
|
5
6
|
/// The main PyO3 module for wildflow.splat
|
6
7
|
#[pymodule]
|
@@ -9,5 +10,10 @@ fn _core(m: &Bound<'_, PyModule>) -> PyResult<()> {
|
|
9
10
|
m.add_class::<split::Config>()?;
|
10
11
|
m.add_class::<split::Patch>()?;
|
11
12
|
m.add_function(wrap_pyfunction!(split::split_ply, m)?)?;
|
13
|
+
|
14
|
+
// Export patches functionality
|
15
|
+
m.add_class::<patches::BoundingBox>()?;
|
16
|
+
m.add_function(wrap_pyfunction!(patches::patches, m)?)?;
|
17
|
+
|
12
18
|
Ok(())
|
13
19
|
}
|