vibephysics 0.2.2__tar.gz → 0.2.3__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.
- {vibephysics-0.2.2/src/vibephysics.egg-info → vibephysics-0.2.3}/PKG-INFO +65 -35
- {vibephysics-0.2.2 → vibephysics-0.2.3}/README.md +64 -34
- {vibephysics-0.2.2 → vibephysics-0.2.3}/pyproject.toml +1 -1
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/__init__.py +1 -1
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/mapping/__init__.py +2 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/mapping/colmap.py +2 -2
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/mapping/glomap.py +1 -1
- vibephysics-0.2.3/src/vibephysics/mapping/map_visual.py +274 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3/src/vibephysics.egg-info}/PKG-INFO +65 -35
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics.egg-info/SOURCES.txt +1 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/LICENSE +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/MANIFEST.in +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/setup.cfg +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/annotation/__init__.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/annotation/base.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/annotation/bbox.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/annotation/manager.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/annotation/motion_trail.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/annotation/point_tracking.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/camera/__init__.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/camera/base.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/camera/center.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/camera/following.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/camera/manager.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/camera/mounted.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/README.md +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/__init__.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/go2.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/ground.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/lighting.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/materials.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/objects.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/open_duck.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/physics.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/robot.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/trajectory.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/foundation/water.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/mapping/pipeline.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/mapping/utils.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/setup/__init__.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/setup/exporter.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/setup/gsplat.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/setup/importer.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/setup/scene.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics/setup/viewport.py +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics.egg-info/dependency_links.txt +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics.egg-info/entry_points.txt +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics.egg-info/requires.txt +0 -0
- {vibephysics-0.2.2 → vibephysics-0.2.3}/src/vibephysics.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vibephysics
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Physics simulation and annotation tools for Blender
|
|
5
5
|
Author-email: tsunyi <tsunyi@mimiaigen.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/yourusername/vibephysics
|
|
@@ -33,6 +33,47 @@ Requires-Dist: ruff; extra == "dev"
|
|
|
33
33
|
|
|
34
34
|
**A lightweight Blender physics simulation framework for creating realistic robot animations, rigid body physics, water dynamics, and comprehensive annotation tools — all running efficiently on CPU.**
|
|
35
35
|
|
|
36
|
+
## ⚙️ Installation (MacOS)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 1. Create environment
|
|
40
|
+
conda create -n vibephysics python=3.11
|
|
41
|
+
conda activate vibephysics
|
|
42
|
+
|
|
43
|
+
# 2. Install core package (includes COLMAP mapping & Blender simulation)
|
|
44
|
+
pip install vibephysics
|
|
45
|
+
|
|
46
|
+
# 3. (Optional) Install GLOMAP backend
|
|
47
|
+
# Linux users: refer to "Linux System Dependencies" below first
|
|
48
|
+
pip install git+https://github.com/shamangary/glomap.git
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 🐧 Linux (Ubuntu) System Dependencies
|
|
52
|
+
If you are on Linux and want to use the **GLOMAP** or **COLMAP** backends, you must install the following C++ development libraries to enable successful compilation:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
sudo apt-get update
|
|
56
|
+
sudo apt-get install -y \
|
|
57
|
+
libeigen3-dev \
|
|
58
|
+
libceres-dev \
|
|
59
|
+
libgoogle-glog-dev \
|
|
60
|
+
libboost-all-dev \
|
|
61
|
+
libsuitesparse-dev \
|
|
62
|
+
libsqlite3-dev \
|
|
63
|
+
libgflags-dev \
|
|
64
|
+
libfreeimage-dev \
|
|
65
|
+
libmetis-dev
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## ⚠️ Troubleshooting (Linker Errors)
|
|
69
|
+
If you are using **Anaconda** on Linux and see an error like `relocation R_X86_64_TPOFF32 ... can not be used when making a shared object`, it is due to a conflict with the Anaconda linker. Fix it by forcing the compiler to use the global-dynamic TLS model:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export CXXFLAGS="$CXXFLAGS -fPIC -ftls-model=global-dynamic"
|
|
73
|
+
export CFLAGS="$CFLAGS -fPIC"
|
|
74
|
+
pip install git+https://github.com/shamangary/glomap.git
|
|
75
|
+
```
|
|
76
|
+
|
|
36
77
|
## 🎬 Example Results (`sh run_robot.sh`)
|
|
37
78
|
|
|
38
79
|

|
|
@@ -93,37 +134,6 @@ Perfect for researchers, animators, and robotics engineers who need physics simu
|
|
|
93
134
|
- **Open Duck**: We use the [Open Duck blender model](https://github.com/pollen-robotics/Open_Duck_Blender) as demo. We do not own the model. Please refer to the original github repo.
|
|
94
135
|
- **Unitree Go2**: We use the [Unitree Go2 USD model](https://huggingface.co/datasets/unitreerobotics/unitree_model). The model is auto-downloaded when running Go2 examples. We do not own the model.
|
|
95
136
|
|
|
96
|
-
## ⚙️ Installation
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
# Create and activate environment
|
|
100
|
-
conda create -n vibephysics python=3.11
|
|
101
|
-
conda activate vibephysics
|
|
102
|
-
|
|
103
|
-
# Install vibephysics
|
|
104
|
-
pip install vibephysics
|
|
105
|
-
|
|
106
|
-
# Or install from source
|
|
107
|
-
git clone https://github.com/mimiaigen/vibephysics
|
|
108
|
-
cd vibephysics
|
|
109
|
-
pip install -e .
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### 🗺️ Mapping & Reconstruction
|
|
113
|
-
The core mapping tools are now built-in!
|
|
114
|
-
|
|
115
|
-
1. **Incremental COLMAP**: Available immediately after `pip install vibephysics`.
|
|
116
|
-
2. **Global GLOMAP**: Just run your first mapping task! `vibephysics` will automatically prompt and install the optimized GLOMAP backend from GitHub.
|
|
117
|
-
*(Note: This requires a one-time C++ build which takes a few minutes).*
|
|
118
|
-
|
|
119
|
-
### Requirements for Simulations
|
|
120
|
-
If you intend to run physics simulations, you also need to install Blender's Python module:
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Install Blender module
|
|
124
|
-
pip install bpy
|
|
125
|
-
```
|
|
126
|
-
|
|
127
137
|
## Quick Start
|
|
128
138
|
|
|
129
139
|
```bash
|
|
@@ -310,7 +320,7 @@ VibePhysics integrates high-performance Structure-from-Motion (SfM) engines to c
|
|
|
310
320
|
from vibephysics import mapping
|
|
311
321
|
|
|
312
322
|
# 1. Simple Usage (Only image_path is REQUIRED)
|
|
313
|
-
# Defaults: glomap engine, exhaustive matcher,
|
|
323
|
+
# Defaults: glomap engine, exhaustive matcher, PINHOLE camera
|
|
314
324
|
mapping.glomap_pipeline(image_path="path/to/images")
|
|
315
325
|
|
|
316
326
|
# 2. COLMAP Incremental Pipeline
|
|
@@ -322,7 +332,7 @@ mapping.glomap_pipeline(
|
|
|
322
332
|
output_path="output/dir", # Optional: Defaults to image_path/../mapping_output/
|
|
323
333
|
database_path="path/to/database.db", # Optional: Defaults to output_path/sparse/database.db
|
|
324
334
|
matcher="exhaustive", # Optional: "exhaustive" (default) or "sequential"
|
|
325
|
-
camera_model="
|
|
335
|
+
camera_model="PINHOLE", # Optional: "PINHOLE" (default), "SIMPLE_RADIAL", "OPENCV", etc.
|
|
326
336
|
verbose=True # Optional: Set to False to suppress logs
|
|
327
337
|
)
|
|
328
338
|
```
|
|
@@ -333,7 +343,27 @@ mapping.glomap_pipeline(
|
|
|
333
343
|
| **`output_path`** | No | `mapping_output/` | Directory for results. Creates `sparse/0` and symlinked `images/`. |
|
|
334
344
|
| **`database_path`** | No | `database.db` | Optional path to an existing COLMAP database. |
|
|
335
345
|
| **`matcher`** | No | `exhaustive` | Matching algorithm: `exhaustive` or `sequential`. |
|
|
336
|
-
| **`camera_model`** | No | `
|
|
346
|
+
| **`camera_model`** | No | `PINHOLE` | COLMAP camera model (e.g., `PINHOLE`, `OPENCV`). |
|
|
347
|
+
|
|
348
|
+
### 🎨 Visualization in Blender
|
|
349
|
+
|
|
350
|
+
You can load your Colmap/GLOMAP reconstruction directly into Blender for inspection, featuring colored point clouds with high-visibility Geometry Node spheres and correct camera poses.
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
from vibephysics import mapping
|
|
354
|
+
|
|
355
|
+
# Load a sparse model folder (containing cameras.bin, points3D.bin etc.)
|
|
356
|
+
mapping.load_colmap_reconstruction(
|
|
357
|
+
input_path="output/mapping_output/sparse/0",
|
|
358
|
+
point_size=0.01 # Adjust point blob size for visibility
|
|
359
|
+
)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Run the Demo:**
|
|
363
|
+
```bash
|
|
364
|
+
# Visualize an existing reconstruction
|
|
365
|
+
python examples/colmap_format/demo_glomap.py --sparse /path/to/sparse/0 --point-size 0.02
|
|
366
|
+
```
|
|
337
367
|
|
|
338
368
|
## Gaussian Splatting (3DGS) (BETA)
|
|
339
369
|
|
|
@@ -4,6 +4,47 @@
|
|
|
4
4
|
|
|
5
5
|
**A lightweight Blender physics simulation framework for creating realistic robot animations, rigid body physics, water dynamics, and comprehensive annotation tools — all running efficiently on CPU.**
|
|
6
6
|
|
|
7
|
+
## ⚙️ Installation (MacOS)
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# 1. Create environment
|
|
11
|
+
conda create -n vibephysics python=3.11
|
|
12
|
+
conda activate vibephysics
|
|
13
|
+
|
|
14
|
+
# 2. Install core package (includes COLMAP mapping & Blender simulation)
|
|
15
|
+
pip install vibephysics
|
|
16
|
+
|
|
17
|
+
# 3. (Optional) Install GLOMAP backend
|
|
18
|
+
# Linux users: refer to "Linux System Dependencies" below first
|
|
19
|
+
pip install git+https://github.com/shamangary/glomap.git
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## 🐧 Linux (Ubuntu) System Dependencies
|
|
23
|
+
If you are on Linux and want to use the **GLOMAP** or **COLMAP** backends, you must install the following C++ development libraries to enable successful compilation:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
sudo apt-get update
|
|
27
|
+
sudo apt-get install -y \
|
|
28
|
+
libeigen3-dev \
|
|
29
|
+
libceres-dev \
|
|
30
|
+
libgoogle-glog-dev \
|
|
31
|
+
libboost-all-dev \
|
|
32
|
+
libsuitesparse-dev \
|
|
33
|
+
libsqlite3-dev \
|
|
34
|
+
libgflags-dev \
|
|
35
|
+
libfreeimage-dev \
|
|
36
|
+
libmetis-dev
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## ⚠️ Troubleshooting (Linker Errors)
|
|
40
|
+
If you are using **Anaconda** on Linux and see an error like `relocation R_X86_64_TPOFF32 ... can not be used when making a shared object`, it is due to a conflict with the Anaconda linker. Fix it by forcing the compiler to use the global-dynamic TLS model:
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
export CXXFLAGS="$CXXFLAGS -fPIC -ftls-model=global-dynamic"
|
|
44
|
+
export CFLAGS="$CFLAGS -fPIC"
|
|
45
|
+
pip install git+https://github.com/shamangary/glomap.git
|
|
46
|
+
```
|
|
47
|
+
|
|
7
48
|
## 🎬 Example Results (`sh run_robot.sh`)
|
|
8
49
|
|
|
9
50
|

|
|
@@ -64,37 +105,6 @@ Perfect for researchers, animators, and robotics engineers who need physics simu
|
|
|
64
105
|
- **Open Duck**: We use the [Open Duck blender model](https://github.com/pollen-robotics/Open_Duck_Blender) as demo. We do not own the model. Please refer to the original github repo.
|
|
65
106
|
- **Unitree Go2**: We use the [Unitree Go2 USD model](https://huggingface.co/datasets/unitreerobotics/unitree_model). The model is auto-downloaded when running Go2 examples. We do not own the model.
|
|
66
107
|
|
|
67
|
-
## ⚙️ Installation
|
|
68
|
-
|
|
69
|
-
```bash
|
|
70
|
-
# Create and activate environment
|
|
71
|
-
conda create -n vibephysics python=3.11
|
|
72
|
-
conda activate vibephysics
|
|
73
|
-
|
|
74
|
-
# Install vibephysics
|
|
75
|
-
pip install vibephysics
|
|
76
|
-
|
|
77
|
-
# Or install from source
|
|
78
|
-
git clone https://github.com/mimiaigen/vibephysics
|
|
79
|
-
cd vibephysics
|
|
80
|
-
pip install -e .
|
|
81
|
-
```
|
|
82
|
-
|
|
83
|
-
### 🗺️ Mapping & Reconstruction
|
|
84
|
-
The core mapping tools are now built-in!
|
|
85
|
-
|
|
86
|
-
1. **Incremental COLMAP**: Available immediately after `pip install vibephysics`.
|
|
87
|
-
2. **Global GLOMAP**: Just run your first mapping task! `vibephysics` will automatically prompt and install the optimized GLOMAP backend from GitHub.
|
|
88
|
-
*(Note: This requires a one-time C++ build which takes a few minutes).*
|
|
89
|
-
|
|
90
|
-
### Requirements for Simulations
|
|
91
|
-
If you intend to run physics simulations, you also need to install Blender's Python module:
|
|
92
|
-
|
|
93
|
-
```bash
|
|
94
|
-
# Install Blender module
|
|
95
|
-
pip install bpy
|
|
96
|
-
```
|
|
97
|
-
|
|
98
108
|
## Quick Start
|
|
99
109
|
|
|
100
110
|
```bash
|
|
@@ -281,7 +291,7 @@ VibePhysics integrates high-performance Structure-from-Motion (SfM) engines to c
|
|
|
281
291
|
from vibephysics import mapping
|
|
282
292
|
|
|
283
293
|
# 1. Simple Usage (Only image_path is REQUIRED)
|
|
284
|
-
# Defaults: glomap engine, exhaustive matcher,
|
|
294
|
+
# Defaults: glomap engine, exhaustive matcher, PINHOLE camera
|
|
285
295
|
mapping.glomap_pipeline(image_path="path/to/images")
|
|
286
296
|
|
|
287
297
|
# 2. COLMAP Incremental Pipeline
|
|
@@ -293,7 +303,7 @@ mapping.glomap_pipeline(
|
|
|
293
303
|
output_path="output/dir", # Optional: Defaults to image_path/../mapping_output/
|
|
294
304
|
database_path="path/to/database.db", # Optional: Defaults to output_path/sparse/database.db
|
|
295
305
|
matcher="exhaustive", # Optional: "exhaustive" (default) or "sequential"
|
|
296
|
-
camera_model="
|
|
306
|
+
camera_model="PINHOLE", # Optional: "PINHOLE" (default), "SIMPLE_RADIAL", "OPENCV", etc.
|
|
297
307
|
verbose=True # Optional: Set to False to suppress logs
|
|
298
308
|
)
|
|
299
309
|
```
|
|
@@ -304,7 +314,27 @@ mapping.glomap_pipeline(
|
|
|
304
314
|
| **`output_path`** | No | `mapping_output/` | Directory for results. Creates `sparse/0` and symlinked `images/`. |
|
|
305
315
|
| **`database_path`** | No | `database.db` | Optional path to an existing COLMAP database. |
|
|
306
316
|
| **`matcher`** | No | `exhaustive` | Matching algorithm: `exhaustive` or `sequential`. |
|
|
307
|
-
| **`camera_model`** | No | `
|
|
317
|
+
| **`camera_model`** | No | `PINHOLE` | COLMAP camera model (e.g., `PINHOLE`, `OPENCV`). |
|
|
318
|
+
|
|
319
|
+
### 🎨 Visualization in Blender
|
|
320
|
+
|
|
321
|
+
You can load your Colmap/GLOMAP reconstruction directly into Blender for inspection, featuring colored point clouds with high-visibility Geometry Node spheres and correct camera poses.
|
|
322
|
+
|
|
323
|
+
```python
|
|
324
|
+
from vibephysics import mapping
|
|
325
|
+
|
|
326
|
+
# Load a sparse model folder (containing cameras.bin, points3D.bin etc.)
|
|
327
|
+
mapping.load_colmap_reconstruction(
|
|
328
|
+
input_path="output/mapping_output/sparse/0",
|
|
329
|
+
point_size=0.01 # Adjust point blob size for visibility
|
|
330
|
+
)
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
**Run the Demo:**
|
|
334
|
+
```bash
|
|
335
|
+
# Visualize an existing reconstruction
|
|
336
|
+
python examples/colmap_format/demo_glomap.py --sparse /path/to/sparse/0 --point-size 0.02
|
|
337
|
+
```
|
|
308
338
|
|
|
309
339
|
## Gaussian Splatting (3DGS) (BETA)
|
|
310
340
|
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
from .colmap import colmap_pipeline, run_colmap_stage, run_incremental_mapping_stage
|
|
2
2
|
from .glomap import glomap_pipeline, run_glomap_stage
|
|
3
|
+
from .map_visual import load_colmap_reconstruction
|
|
3
4
|
from .utils import prepare_output_directory
|
|
4
5
|
|
|
5
6
|
__all__ = [
|
|
@@ -8,5 +9,6 @@ __all__ = [
|
|
|
8
9
|
"run_colmap_stage",
|
|
9
10
|
"run_incremental_mapping_stage",
|
|
10
11
|
"run_glomap_stage",
|
|
12
|
+
"load_colmap_reconstruction",
|
|
11
13
|
"prepare_output_directory"
|
|
12
14
|
]
|
|
@@ -7,7 +7,7 @@ from .utils import prepare_output_directory
|
|
|
7
7
|
def run_colmap_stage(
|
|
8
8
|
image_path: Path,
|
|
9
9
|
database_path: Path,
|
|
10
|
-
camera_model: str = "
|
|
10
|
+
camera_model: str = "PINHOLE",
|
|
11
11
|
matcher: str = "exhaustive",
|
|
12
12
|
verbose: bool = True
|
|
13
13
|
) -> int:
|
|
@@ -86,7 +86,7 @@ def colmap_pipeline(
|
|
|
86
86
|
output_path: str | Path | None = None,
|
|
87
87
|
database_path: str | Path | None = None,
|
|
88
88
|
matcher: str = "exhaustive",
|
|
89
|
-
camera_model: str = "
|
|
89
|
+
camera_model: str = "PINHOLE",
|
|
90
90
|
verbose: bool = True
|
|
91
91
|
) -> int:
|
|
92
92
|
"""
|
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
import bpy
|
|
2
|
+
import pycolmap
|
|
3
|
+
import numpy as np
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
import math
|
|
6
|
+
|
|
7
|
+
def create_camera_object(image, camera, collection, scale=0.1):
|
|
8
|
+
"""
|
|
9
|
+
Create a Blender camera object from a Colmap image and camera.
|
|
10
|
+
"""
|
|
11
|
+
name = image.name
|
|
12
|
+
|
|
13
|
+
# Colmap pose is World-to-Camera (R, t)
|
|
14
|
+
# pycolmap 3.x uses image.cam_from_world() method
|
|
15
|
+
if hasattr(image, "cam_from_world") and callable(image.cam_from_world):
|
|
16
|
+
pose = image.cam_from_world()
|
|
17
|
+
rot_mat = pose.rotation.matrix()
|
|
18
|
+
tvec = pose.translation
|
|
19
|
+
else:
|
|
20
|
+
# Fallback for older pycolmap
|
|
21
|
+
qvec = getattr(image, "qvec", np.array([1, 0, 0, 0]))
|
|
22
|
+
tvec = getattr(image, "tvec", np.zeros(3))
|
|
23
|
+
# Manual qvec to rotmat if function is missing
|
|
24
|
+
if hasattr(pycolmap, "qvec_to_rotmat"):
|
|
25
|
+
rot_mat = pycolmap.qvec_to_rotmat(qvec)
|
|
26
|
+
else:
|
|
27
|
+
# Standard Hamilton quaternion to rotation matrix
|
|
28
|
+
w, x, y, z = qvec
|
|
29
|
+
rot_mat = np.array([
|
|
30
|
+
[1 - 2*y**2 - 2*z**2, 2*x*y - 2*z*w, 2*x*z + 2*y*w],
|
|
31
|
+
[2*x*y + 2*z*w, 1 - 2*x**2 - 2*z**2, 2*y*z - 2*x*w],
|
|
32
|
+
[2*x*z - 2*y*w, 2*y*z + 2*x*w, 1 - 2*x**2 - 2*y**2]
|
|
33
|
+
])
|
|
34
|
+
|
|
35
|
+
# Inverse rotation and translation to get Camera-to-World
|
|
36
|
+
rot_mat_inv = rot_mat.T
|
|
37
|
+
tvec_inv = -rot_mat_inv @ tvec
|
|
38
|
+
|
|
39
|
+
# Create Camera Data
|
|
40
|
+
cam_data = bpy.data.cameras.new(name=f"CamData_{name}")
|
|
41
|
+
cam_obj = bpy.data.objects.new(name=name, object_data=cam_data)
|
|
42
|
+
collection.objects.link(cam_obj)
|
|
43
|
+
|
|
44
|
+
# Construct 4x4 matrix in OpenCV frame (X-right, Y-down, Z-forward)
|
|
45
|
+
mat_world_cv = np.eye(4)
|
|
46
|
+
mat_world_cv[:3, :3] = rot_mat_inv
|
|
47
|
+
mat_world_cv[:3, 3] = tvec_inv
|
|
48
|
+
|
|
49
|
+
# Convert from OpenCV to Blender coordinate system
|
|
50
|
+
# Blender camera looks down -Z, Y is up.
|
|
51
|
+
# We rotate 180 degrees around X to flip Y and Z.
|
|
52
|
+
transform_matrix = np.array([
|
|
53
|
+
[1, 0, 0, 0],
|
|
54
|
+
[0, -1, 0, 0],
|
|
55
|
+
[0, 0, -1, 0],
|
|
56
|
+
[0, 0, 0, 1]
|
|
57
|
+
])
|
|
58
|
+
|
|
59
|
+
final_matrix = mat_world_cv @ transform_matrix
|
|
60
|
+
|
|
61
|
+
# Assign to object
|
|
62
|
+
import mathutils
|
|
63
|
+
m = mathutils.Matrix(final_matrix.tolist())
|
|
64
|
+
cam_obj.matrix_world = m
|
|
65
|
+
|
|
66
|
+
# Set camera intrinsics
|
|
67
|
+
# Params mapping depends on camera model
|
|
68
|
+
width = camera.width
|
|
69
|
+
height = camera.height
|
|
70
|
+
cam_data.sensor_width = 36.0 # standard 36mm sensor
|
|
71
|
+
|
|
72
|
+
# f_mm = f_px * sensor_width / width_px
|
|
73
|
+
f_px = 1000.0 # fallback
|
|
74
|
+
|
|
75
|
+
# Get camera model name
|
|
76
|
+
if hasattr(camera, "model") and hasattr(camera.model, "name"):
|
|
77
|
+
model = camera.model.name
|
|
78
|
+
else:
|
|
79
|
+
model = getattr(camera, "model_name", "UNKNOWN")
|
|
80
|
+
|
|
81
|
+
params = camera.params
|
|
82
|
+
|
|
83
|
+
if model in ["SIMPLE_PINHOLE", "SIMPLE_RADIAL"]:
|
|
84
|
+
# f, cx, cy
|
|
85
|
+
f_px = params[0]
|
|
86
|
+
elif model in ["PINHOLE", "OPENCV", "FULL_OPENCV"]:
|
|
87
|
+
# fx, fy, cx, cy
|
|
88
|
+
f_px = (params[0] + params[1]) / 2.0
|
|
89
|
+
|
|
90
|
+
cam_data.lens = f_px * cam_data.sensor_width / width
|
|
91
|
+
|
|
92
|
+
return cam_obj
|
|
93
|
+
|
|
94
|
+
def create_point_cloud(points3D, collection, name="PointCloud", point_size=0.03):
|
|
95
|
+
"""
|
|
96
|
+
Create a point cloud visualization using a mesh with vertices and colors.
|
|
97
|
+
Uses Geometry Nodes to make points visible as spheres.
|
|
98
|
+
"""
|
|
99
|
+
mesh = bpy.data.meshes.new(name=name)
|
|
100
|
+
obj = bpy.data.objects.new(name=name, object_data=mesh)
|
|
101
|
+
collection.objects.link(obj)
|
|
102
|
+
|
|
103
|
+
# Extract points and colors
|
|
104
|
+
xyz = []
|
|
105
|
+
rgb = []
|
|
106
|
+
|
|
107
|
+
for p_id, p in points3D.items():
|
|
108
|
+
xyz.append(p.xyz)
|
|
109
|
+
rgb.append(p.color / 255.0) # Normalize to 0-1
|
|
110
|
+
|
|
111
|
+
if not xyz:
|
|
112
|
+
print("No points found in reconstruction.")
|
|
113
|
+
return obj
|
|
114
|
+
|
|
115
|
+
# Create mesh
|
|
116
|
+
mesh.from_pydata(xyz, [], [])
|
|
117
|
+
mesh.update()
|
|
118
|
+
|
|
119
|
+
# Add colors as a generic attribute
|
|
120
|
+
if rgb:
|
|
121
|
+
# Check Blender version for attribute creation
|
|
122
|
+
if hasattr(mesh.attributes, "new"):
|
|
123
|
+
color_attr = mesh.attributes.new(name="Color", type='FLOAT_COLOR', domain='POINT')
|
|
124
|
+
color_attr.data.foreach_set("color", [c for color in rgb for c in (*color, 1.0)]) # RGBA
|
|
125
|
+
|
|
126
|
+
# Simple Geometry Nodes setup to render points as spheres
|
|
127
|
+
modifier = obj.modifiers.new(name="PointVisualizer", type='NODES')
|
|
128
|
+
|
|
129
|
+
# Setup node tree
|
|
130
|
+
node_tree = bpy.data.node_groups.new(name="PointVisualizerTree", type='GeometryNodeTree')
|
|
131
|
+
|
|
132
|
+
# In Blender 4.0+, we use interface to add sockets
|
|
133
|
+
if hasattr(node_tree, "interface"):
|
|
134
|
+
if not any(item.name == "Geometry" for item in node_tree.interface.items_tree if item.item_type == 'SOCKET'):
|
|
135
|
+
node_tree.interface.new_socket(name="Geometry", in_out='INPUT', socket_type='NodeSocketGeometry')
|
|
136
|
+
node_tree.interface.new_socket(name="Geometry", in_out='OUTPUT', socket_type='NodeSocketGeometry')
|
|
137
|
+
else:
|
|
138
|
+
# Older Blender fallback
|
|
139
|
+
if "Geometry" not in node_tree.inputs:
|
|
140
|
+
node_tree.inputs.new('NodeSocketGeometry', "Geometry")
|
|
141
|
+
if "Geometry" not in node_tree.outputs:
|
|
142
|
+
node_tree.outputs.new('NodeSocketGeometry', "Geometry")
|
|
143
|
+
|
|
144
|
+
links = node_tree.links
|
|
145
|
+
nodes = node_tree.nodes
|
|
146
|
+
|
|
147
|
+
# Clear default nodes
|
|
148
|
+
nodes.clear()
|
|
149
|
+
|
|
150
|
+
# Input/Output
|
|
151
|
+
node_in = nodes.new('NodeGroupInput')
|
|
152
|
+
node_out = nodes.new('NodeGroupOutput')
|
|
153
|
+
|
|
154
|
+
# Point to Volume / Instances
|
|
155
|
+
node_m2p = nodes.new('GeometryNodeMeshToPoints')
|
|
156
|
+
node_inst = nodes.new('GeometryNodeInstanceOnPoints')
|
|
157
|
+
node_sph = nodes.new('GeometryNodeMeshIcoSphere')
|
|
158
|
+
node_sph.inputs['Radius'].default_value = point_size
|
|
159
|
+
node_sph.inputs['Subdivisions'].default_value = 1
|
|
160
|
+
|
|
161
|
+
# Realize Instances to propagate attributes (like Color)
|
|
162
|
+
node_realize = nodes.new('GeometryNodeRealizeInstances')
|
|
163
|
+
|
|
164
|
+
# Material
|
|
165
|
+
node_mat = nodes.new('GeometryNodeSetMaterial')
|
|
166
|
+
|
|
167
|
+
# Material setup
|
|
168
|
+
mat_name = "PointCloudMaterial"
|
|
169
|
+
if mat_name not in bpy.data.materials:
|
|
170
|
+
mat = bpy.data.materials.new(name=mat_name)
|
|
171
|
+
mat.use_nodes = True
|
|
172
|
+
nodes_mat = mat.node_tree.nodes
|
|
173
|
+
links_mat = mat.node_tree.links
|
|
174
|
+
nodes_mat.clear()
|
|
175
|
+
|
|
176
|
+
node_out_mat = nodes_mat.new('ShaderNodeOutputMaterial')
|
|
177
|
+
node_principled = nodes_mat.new('ShaderNodeBsdfPrincipled')
|
|
178
|
+
# Use Attribute node to get the vertex color
|
|
179
|
+
node_attr = nodes_mat.new('ShaderNodeAttribute')
|
|
180
|
+
node_attr.attribute_name = "Color"
|
|
181
|
+
node_attr.attribute_type = 'GEOMETRY'
|
|
182
|
+
|
|
183
|
+
links_mat.new(node_attr.outputs['Color'], node_principled.inputs['Base Color'])
|
|
184
|
+
links_mat.new(node_principled.outputs['BSDF'], node_out_mat.inputs['Surface'])
|
|
185
|
+
else:
|
|
186
|
+
mat = bpy.data.materials[mat_name]
|
|
187
|
+
|
|
188
|
+
# Assign material to object slots (important for some Blender versions to see attributes)
|
|
189
|
+
if mat.name not in obj.data.materials:
|
|
190
|
+
obj.data.materials.append(mat)
|
|
191
|
+
|
|
192
|
+
node_mat.inputs['Material'].default_value = mat
|
|
193
|
+
|
|
194
|
+
# Link nodes
|
|
195
|
+
links.new(node_in.outputs[0], node_m2p.inputs['Mesh'])
|
|
196
|
+
links.new(node_m2p.outputs['Points'], node_inst.inputs['Points'])
|
|
197
|
+
links.new(node_sph.outputs['Mesh'], node_inst.inputs['Instance'])
|
|
198
|
+
links.new(node_inst.outputs['Instances'], node_realize.inputs['Geometry'])
|
|
199
|
+
links.new(node_realize.outputs['Geometry'], node_mat.inputs['Geometry'])
|
|
200
|
+
links.new(node_mat.outputs['Geometry'], node_out.inputs[0])
|
|
201
|
+
|
|
202
|
+
modifier.node_group = node_tree
|
|
203
|
+
|
|
204
|
+
# Attempt to set viewport shading to MATERIAL for better UX
|
|
205
|
+
if bpy.context.screen:
|
|
206
|
+
for area in bpy.context.screen.areas:
|
|
207
|
+
if area.type == 'VIEW_3D':
|
|
208
|
+
for space in area.spaces:
|
|
209
|
+
if space.type == 'VIEW_3D':
|
|
210
|
+
space.shading.type = 'MATERIAL'
|
|
211
|
+
|
|
212
|
+
return obj
|
|
213
|
+
|
|
214
|
+
def load_colmap_reconstruction(
|
|
215
|
+
input_path: str, # Path to sparse/0 folder
|
|
216
|
+
collection_name: str = "Reconstruction",
|
|
217
|
+
import_cameras: bool = True,
|
|
218
|
+
import_points: bool = True,
|
|
219
|
+
camera_scale: float = 0.1,
|
|
220
|
+
point_size: float = 0.03,
|
|
221
|
+
rotation: tuple = (-90, 0, 0) # Global rotation in degrees (Euler XYZ)
|
|
222
|
+
):
|
|
223
|
+
"""
|
|
224
|
+
Load Colmap reconstruction output (sparse folder) into Blender.
|
|
225
|
+
"""
|
|
226
|
+
input_dir = Path(input_path)
|
|
227
|
+
if not input_dir.exists():
|
|
228
|
+
print(f"Error: Path {input_dir} does not exist.")
|
|
229
|
+
return
|
|
230
|
+
|
|
231
|
+
print(f"Loading Colmap reconstruction from {input_dir}...")
|
|
232
|
+
recon = pycolmap.Reconstruction(input_dir)
|
|
233
|
+
|
|
234
|
+
# Create collection
|
|
235
|
+
if collection_name in bpy.data.collections:
|
|
236
|
+
col = bpy.data.collections[collection_name]
|
|
237
|
+
else:
|
|
238
|
+
col = bpy.data.collections.new(collection_name)
|
|
239
|
+
bpy.context.scene.collection.children.link(col)
|
|
240
|
+
|
|
241
|
+
# Create a root object for the whole reconstruction to allow global manipulation
|
|
242
|
+
root_name = f"{collection_name}_Root"
|
|
243
|
+
if root_name in bpy.data.objects:
|
|
244
|
+
root_obj = bpy.data.objects[root_name]
|
|
245
|
+
else:
|
|
246
|
+
root_obj = bpy.data.objects.new(root_name, None)
|
|
247
|
+
col.objects.link(root_obj)
|
|
248
|
+
|
|
249
|
+
# Apply global rotation to the root
|
|
250
|
+
root_obj.rotation_mode = 'XYZ'
|
|
251
|
+
root_obj.rotation_euler = [math.radians(a) for a in rotation]
|
|
252
|
+
|
|
253
|
+
if import_points:
|
|
254
|
+
print(f"Importing {len(recon.points3D)} points...")
|
|
255
|
+
pc_obj = create_point_cloud(recon.points3D, col, point_size=point_size)
|
|
256
|
+
pc_obj.parent = root_obj
|
|
257
|
+
|
|
258
|
+
if import_cameras:
|
|
259
|
+
print(f"Importing {len(recon.images)} cameras...")
|
|
260
|
+
for img_id, image in recon.images.items():
|
|
261
|
+
if image.camera_id in recon.cameras:
|
|
262
|
+
cam = recon.cameras[image.camera_id]
|
|
263
|
+
cam_obj = create_camera_object(image, cam, col, scale=camera_scale)
|
|
264
|
+
cam_obj.parent = root_obj
|
|
265
|
+
# Keep the same world matrix when parenting if the root has no rotation yet
|
|
266
|
+
# or just set it relative to parent.
|
|
267
|
+
# Since we set root rotation ABOVE, we should set matrix_world AFTER parenting
|
|
268
|
+
# or use matrix_local if we want it to be relative.
|
|
269
|
+
# The create_camera_object returns an object with matrix_world set for the SfM space.
|
|
270
|
+
# If we parent it to root_obj, and then set matrix_world again,
|
|
271
|
+
# it will stay in the correct spot while being a child.
|
|
272
|
+
|
|
273
|
+
print("Done.")
|
|
274
|
+
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: vibephysics
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: Physics simulation and annotation tools for Blender
|
|
5
5
|
Author-email: tsunyi <tsunyi@mimiaigen.com>
|
|
6
6
|
Project-URL: Homepage, https://github.com/yourusername/vibephysics
|
|
@@ -33,6 +33,47 @@ Requires-Dist: ruff; extra == "dev"
|
|
|
33
33
|
|
|
34
34
|
**A lightweight Blender physics simulation framework for creating realistic robot animations, rigid body physics, water dynamics, and comprehensive annotation tools — all running efficiently on CPU.**
|
|
35
35
|
|
|
36
|
+
## ⚙️ Installation (MacOS)
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
# 1. Create environment
|
|
40
|
+
conda create -n vibephysics python=3.11
|
|
41
|
+
conda activate vibephysics
|
|
42
|
+
|
|
43
|
+
# 2. Install core package (includes COLMAP mapping & Blender simulation)
|
|
44
|
+
pip install vibephysics
|
|
45
|
+
|
|
46
|
+
# 3. (Optional) Install GLOMAP backend
|
|
47
|
+
# Linux users: refer to "Linux System Dependencies" below first
|
|
48
|
+
pip install git+https://github.com/shamangary/glomap.git
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## 🐧 Linux (Ubuntu) System Dependencies
|
|
52
|
+
If you are on Linux and want to use the **GLOMAP** or **COLMAP** backends, you must install the following C++ development libraries to enable successful compilation:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
sudo apt-get update
|
|
56
|
+
sudo apt-get install -y \
|
|
57
|
+
libeigen3-dev \
|
|
58
|
+
libceres-dev \
|
|
59
|
+
libgoogle-glog-dev \
|
|
60
|
+
libboost-all-dev \
|
|
61
|
+
libsuitesparse-dev \
|
|
62
|
+
libsqlite3-dev \
|
|
63
|
+
libgflags-dev \
|
|
64
|
+
libfreeimage-dev \
|
|
65
|
+
libmetis-dev
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## ⚠️ Troubleshooting (Linker Errors)
|
|
69
|
+
If you are using **Anaconda** on Linux and see an error like `relocation R_X86_64_TPOFF32 ... can not be used when making a shared object`, it is due to a conflict with the Anaconda linker. Fix it by forcing the compiler to use the global-dynamic TLS model:
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
export CXXFLAGS="$CXXFLAGS -fPIC -ftls-model=global-dynamic"
|
|
73
|
+
export CFLAGS="$CFLAGS -fPIC"
|
|
74
|
+
pip install git+https://github.com/shamangary/glomap.git
|
|
75
|
+
```
|
|
76
|
+
|
|
36
77
|
## 🎬 Example Results (`sh run_robot.sh`)
|
|
37
78
|
|
|
38
79
|

|
|
@@ -93,37 +134,6 @@ Perfect for researchers, animators, and robotics engineers who need physics simu
|
|
|
93
134
|
- **Open Duck**: We use the [Open Duck blender model](https://github.com/pollen-robotics/Open_Duck_Blender) as demo. We do not own the model. Please refer to the original github repo.
|
|
94
135
|
- **Unitree Go2**: We use the [Unitree Go2 USD model](https://huggingface.co/datasets/unitreerobotics/unitree_model). The model is auto-downloaded when running Go2 examples. We do not own the model.
|
|
95
136
|
|
|
96
|
-
## ⚙️ Installation
|
|
97
|
-
|
|
98
|
-
```bash
|
|
99
|
-
# Create and activate environment
|
|
100
|
-
conda create -n vibephysics python=3.11
|
|
101
|
-
conda activate vibephysics
|
|
102
|
-
|
|
103
|
-
# Install vibephysics
|
|
104
|
-
pip install vibephysics
|
|
105
|
-
|
|
106
|
-
# Or install from source
|
|
107
|
-
git clone https://github.com/mimiaigen/vibephysics
|
|
108
|
-
cd vibephysics
|
|
109
|
-
pip install -e .
|
|
110
|
-
```
|
|
111
|
-
|
|
112
|
-
### 🗺️ Mapping & Reconstruction
|
|
113
|
-
The core mapping tools are now built-in!
|
|
114
|
-
|
|
115
|
-
1. **Incremental COLMAP**: Available immediately after `pip install vibephysics`.
|
|
116
|
-
2. **Global GLOMAP**: Just run your first mapping task! `vibephysics` will automatically prompt and install the optimized GLOMAP backend from GitHub.
|
|
117
|
-
*(Note: This requires a one-time C++ build which takes a few minutes).*
|
|
118
|
-
|
|
119
|
-
### Requirements for Simulations
|
|
120
|
-
If you intend to run physics simulations, you also need to install Blender's Python module:
|
|
121
|
-
|
|
122
|
-
```bash
|
|
123
|
-
# Install Blender module
|
|
124
|
-
pip install bpy
|
|
125
|
-
```
|
|
126
|
-
|
|
127
137
|
## Quick Start
|
|
128
138
|
|
|
129
139
|
```bash
|
|
@@ -310,7 +320,7 @@ VibePhysics integrates high-performance Structure-from-Motion (SfM) engines to c
|
|
|
310
320
|
from vibephysics import mapping
|
|
311
321
|
|
|
312
322
|
# 1. Simple Usage (Only image_path is REQUIRED)
|
|
313
|
-
# Defaults: glomap engine, exhaustive matcher,
|
|
323
|
+
# Defaults: glomap engine, exhaustive matcher, PINHOLE camera
|
|
314
324
|
mapping.glomap_pipeline(image_path="path/to/images")
|
|
315
325
|
|
|
316
326
|
# 2. COLMAP Incremental Pipeline
|
|
@@ -322,7 +332,7 @@ mapping.glomap_pipeline(
|
|
|
322
332
|
output_path="output/dir", # Optional: Defaults to image_path/../mapping_output/
|
|
323
333
|
database_path="path/to/database.db", # Optional: Defaults to output_path/sparse/database.db
|
|
324
334
|
matcher="exhaustive", # Optional: "exhaustive" (default) or "sequential"
|
|
325
|
-
camera_model="
|
|
335
|
+
camera_model="PINHOLE", # Optional: "PINHOLE" (default), "SIMPLE_RADIAL", "OPENCV", etc.
|
|
326
336
|
verbose=True # Optional: Set to False to suppress logs
|
|
327
337
|
)
|
|
328
338
|
```
|
|
@@ -333,7 +343,27 @@ mapping.glomap_pipeline(
|
|
|
333
343
|
| **`output_path`** | No | `mapping_output/` | Directory for results. Creates `sparse/0` and symlinked `images/`. |
|
|
334
344
|
| **`database_path`** | No | `database.db` | Optional path to an existing COLMAP database. |
|
|
335
345
|
| **`matcher`** | No | `exhaustive` | Matching algorithm: `exhaustive` or `sequential`. |
|
|
336
|
-
| **`camera_model`** | No | `
|
|
346
|
+
| **`camera_model`** | No | `PINHOLE` | COLMAP camera model (e.g., `PINHOLE`, `OPENCV`). |
|
|
347
|
+
|
|
348
|
+
### 🎨 Visualization in Blender
|
|
349
|
+
|
|
350
|
+
You can load your Colmap/GLOMAP reconstruction directly into Blender for inspection, featuring colored point clouds with high-visibility Geometry Node spheres and correct camera poses.
|
|
351
|
+
|
|
352
|
+
```python
|
|
353
|
+
from vibephysics import mapping
|
|
354
|
+
|
|
355
|
+
# Load a sparse model folder (containing cameras.bin, points3D.bin etc.)
|
|
356
|
+
mapping.load_colmap_reconstruction(
|
|
357
|
+
input_path="output/mapping_output/sparse/0",
|
|
358
|
+
point_size=0.01 # Adjust point blob size for visibility
|
|
359
|
+
)
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
**Run the Demo:**
|
|
363
|
+
```bash
|
|
364
|
+
# Visualize an existing reconstruction
|
|
365
|
+
python examples/colmap_format/demo_glomap.py --sparse /path/to/sparse/0 --point-size 0.02
|
|
366
|
+
```
|
|
337
367
|
|
|
338
368
|
## Gaussian Splatting (3DGS) (BETA)
|
|
339
369
|
|
|
@@ -36,6 +36,7 @@ src/vibephysics/foundation/water.py
|
|
|
36
36
|
src/vibephysics/mapping/__init__.py
|
|
37
37
|
src/vibephysics/mapping/colmap.py
|
|
38
38
|
src/vibephysics/mapping/glomap.py
|
|
39
|
+
src/vibephysics/mapping/map_visual.py
|
|
39
40
|
src/vibephysics/mapping/pipeline.py
|
|
40
41
|
src/vibephysics/mapping/utils.py
|
|
41
42
|
src/vibephysics/setup/__init__.py
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|