Skip to content

Commit 5811720

Browse files
authored
v2.4.0 (#1247)
- Complete viewer rewrite with OpenGL 3, ImGui UI, multi-select, screenshots, workflows - Automatic Region-Of-Interest (ROI) detection - GPU-based selection and improved rendering - Enhanced dense reconstruction with SfM normals, segmentation from masks - Support for new formats: VGGSFM, GLTF point clouds - Python utilities for depth-maps and mesh reconstruction - Improved CMake and build system
1 parent ce03889 commit 5811720

File tree

234 files changed

+25008
-16143
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

234 files changed

+25008
-16143
lines changed

.clang-format

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
# OpenMVS approximate formatting rules inferred from libs/MVS and libs/Common
2+
---
3+
Language: Cpp
4+
BasedOnStyle: LLVM
5+
6+
# Indentation
7+
UseTab: ForIndentation
8+
IndentWidth: 4
9+
TabWidth: 4
10+
ContinuationIndentWidth: 4
11+
AccessModifierOffset: 0
12+
NamespaceIndentation: None
13+
IndentPPDirectives: BeforeHash
14+
15+
# Line breaking
16+
ColumnLimit: 0 # preserve long lines; project has many >120
17+
ReflowComments: false
18+
KeepEmptyLinesAtTheStartOfBlocks: false
19+
20+
# Braces
21+
BreakBeforeBraces: Custom
22+
BraceWrapping:
23+
AfterClass: true
24+
AfterStruct: true
25+
AfterFunction: true
26+
AfterEnum: false
27+
AfterControlStatement: false
28+
AfterNamespace: false
29+
BeforeElse: false
30+
BeforeCatch: false
31+
SplitEmptyFunction: true
32+
SplitEmptyRecord: true
33+
SplitEmptyNamespace: true
34+
35+
# Pointers/references
36+
DerivePointerAlignment: false
37+
PointerAlignment: Left # Type*& var, const Type& name
38+
39+
# Short constructs on one line
40+
AllowShortBlocksOnASingleLine: Empty
41+
AllowShortCaseLabelsOnASingleLine: true
42+
AllowShortEnumsOnASingleLine: true
43+
AllowShortFunctionsOnASingleLine: All
44+
AllowShortIfStatementsOnASingleLine: false
45+
AllowShortLoopsOnASingleLine: false
46+
47+
# Spacing
48+
SpaceBeforeParens: ControlStatements
49+
SpaceBeforeRangeBasedForLoopColon: true
50+
SpacesInAngles: false
51+
SpacesInCStyleCastParentheses: false
52+
SpacesInParentheses: false
53+
SpaceAfterCStyleCast: false
54+
SpaceInEmptyParentheses: false
55+
SpaceAfterTemplateKeyword: true
56+
Cpp11BracedListStyle: true
57+
58+
# Wrapping/alignment
59+
BinPackParameters: true
60+
BinPackArguments: true
61+
BreakConstructorInitializers: AfterColon
62+
ConstructorInitializerAllOnOneLineOrOnePerLine: false
63+
BreakBeforeBinaryOperators: NonAssignment
64+
AlignConsecutiveMacros: false
65+
AlignConsecutiveAssignments: false
66+
AlignConsecutiveDeclarations: false
67+
AlignTrailingComments: false
68+
69+
# Includes & usings
70+
SortIncludes: false
71+
IncludeBlocks: Preserve
72+
SortUsingDeclarations: false
73+
74+
# Macros
75+
ForEachMacros: ['FOREACH']

.github/copilot-instructions.md

Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# OpenMVS Copilot Instructions
2+
3+
OpenMVS is a multi-view stereo reconstruction library implementing a complete photogrammetry pipeline from camera poses + sparse point-cloud to textured mesh. The codebase is mature C++ with custom framework patterns.
4+
5+
## Project Architecture
6+
7+
### Core Namespaces & Structure
8+
- **MVS namespace**: Core reconstruction algorithms (`libs/MVS/`)
9+
- **VIEWER namespace**: 3D visualization application (`apps/Viewer/`)
10+
- **SEACAVE namespace**: Low-level utilities (`libs/Common/`)
11+
12+
### Key Libraries (libs/)
13+
- `Common/`: Custom framework (types, logging, containers, math utilities)
14+
- `MVS/`: Core MVS algorithms (Scene, Image, Camera, Mesh, PointCloud, etc.)
15+
- `IO/`: File format support (PLY, OBJ, MVS formats)
16+
- `Math/`: Mathematical primitives and operations
17+
18+
### Applications (apps/)
19+
Each app is a standalone executable for specific pipeline stages:
20+
- `DensifyPointCloud`: Dense reconstruction from sparse points
21+
- `ReconstructMesh`: Surface reconstruction from dense points
22+
- `RefineMesh`: Mesh quality improvement
23+
- `TextureMesh`: Apply textures to meshes
24+
- `Viewer`: Interactive 3D visualization with OpenGL
25+
- `Interface*`: Import/export to other pipelines (COLMAP, OpenMVG, etc.)
26+
27+
## Build System & Workflows
28+
29+
### Building
30+
```bash
31+
# Standard build (uses vcpkg for dependencies)
32+
mkdir make && cd make
33+
cmake ..
34+
cmake --build . -j4 # or ninja (generates ninja files)
35+
```
36+
37+
### Key Build Tools
38+
- **vcpkg**: Automatic dependency management (see `vcpkg.json`)
39+
- **CMake**: Primary build system with custom utilities in `build/Utils.cmake`
40+
- **ninja**: Preferred generator (faster than make)
41+
42+
### Development Builds
43+
- Debug builds in `make/bin/Debug/`
44+
- Built executables: `./bin/Debug/Viewer`, `./bin/Debug/DensifyPointCloud`, etc.
45+
- Use `cmake --build . -j4` from `make/` directory for incremental builds
46+
47+
## Code Patterns & Conventions
48+
49+
### Memory Management
50+
- Reference counting with automatic cleanup
51+
- RAII patterns throughout
52+
53+
### Logging & Debugging
54+
```cpp
55+
DEBUG("Message"); // Level 0 (always shown in debug)
56+
DEBUG_EXTRA("Details"); // Level 1 (verbose)
57+
VERBOSE("Info: %s", str); // General logging
58+
```
59+
60+
### Error Handling
61+
- `ASSERT(condition)` for debug checks
62+
- Return false/NULL for failures
63+
64+
### Common Typedefs
65+
```cpp
66+
typedef SEACAVE::Point3f Point3f; // 3D points
67+
typedef SEACAVE::String String; // String type
68+
#define NO_ID ((uint32_t)-1) // Invalid index
69+
```
70+
Most of OpenMVS code uses custom point and matrix types derived from OpenCV types, e.g., `SEACAVE::Point3f`, `SEACAVE::Matrix4f`. Hoewever, some components use Eigen3 types, e.g. `SEACAVE::AABB3d` and `SEACAVE::Ray3d` classes. There custom types support convertion operation to and from Eigen3 types.
71+
72+
SEACAVE::cList template class is a custom vector implementation used throughout the codebase, fully compatible with std::vector. It provides additional functionality such as using or not the constructor for the elements, custom size type, and additional operations like GetMean, GetMedian, Sort, etc.
73+
74+
Often used is also FOREACH macro for iterating over any vector-like container:
75+
```cpp
76+
FOREACH(index, container) {
77+
auto& element = container[index];
78+
// Do something with element
79+
}
80+
```
81+
Similarly, RFOREACH macro iterates in reverse order.
82+
83+
TD_TIMER_START() and TD_TIMER_GET_FMT() macros are used for performance measurements. TD_TIMER_START() (similarly TD_TIMER_STARTD() paird with DEBUG() prints) starts a timer, and TD_TIMER_GET_FMT() returns a formatted string with the elapsed time since the timer was started.
84+
85+
VERBOSE() macro is used for general logging messages. It works similarly to DEBUG() macro, but is intended for critical information, as it always prints regardless of debug level. DEBUG_EXTRA() and DEBUG_ULTIMATE() macros are used for more verbose logging, with DEBUG_ULTIMATE() being the most verbose.
86+
87+
### Configuration
88+
- Build-time config in `ConfigLocal.h` (generated)
89+
- Runtime options via boost::program_options pattern
90+
- Feature flags like `OpenMVS_USE_CUDA`, `OpenMVS_USE_CERES`
91+
- Each library uses a precompiled header (`Common.h`) for common includes, like Eigen, OpenCV, etc.
92+
93+
## Viewer Application Specifics
94+
95+
### Key Classes
96+
- `Scene`: Main data container (MVS::Scene + rendering state)
97+
- `Window`: GLFW window management + input handling
98+
- `Renderer`: OpenGL rendering (points, meshes, cameras)
99+
- `Camera`: View/projection matrices + navigation
100+
- `UI`: ImGui interface components
101+
102+
### Rendering Pipeline
103+
```cpp
104+
window.Run(scene) →
105+
Render(scene) →
106+
renderer->RenderPointCloud/RenderMesh →
107+
OpenGL draw calls
108+
```
109+
110+
### Event System
111+
- GLFW events → Window callbacks → Control system updates
112+
- Render-only-on-change optimization uses `glfwWaitEventsTimeout()`
113+
- `Window::RequestRedraw()` triggers frame updates
114+
115+
## Integration Points
116+
117+
### File Formats
118+
- `.mvs`: Native binary format (boost serialization)
119+
- `.ply`: Point clouds and meshes (ASCII/binary)
120+
- `.obj`: Mesh export with MTL materials
121+
- Interface apps handle external formats (COLMAP, etc.)
122+
123+
### External Dependencies
124+
- **Eigen3**: Linear algebra (matrices, vectors)
125+
- **OpenCV**: Image processing and I/O
126+
- **CGAL**: Computational geometry
127+
- **Boost**: Serialization, program options, containers
128+
- **CUDA**: GPU acceleration (optional)
129+
- **GLFW/OpenGL**: Viewer rendering
130+
131+
### Cross-Component Communication
132+
- `MVS::Scene` is the central data exchange format
133+
- Applications typically: load scene → process → save scene
134+
- Viewer loads and visualizes any stage of the pipeline
135+
136+
## Testing & Debugging
137+
138+
### Running Tests
139+
```bash
140+
# From make/ directory
141+
ctest # Run all tests
142+
./bin/Debug/Tests # Direct test executable
143+
```
144+
145+
### Common Debugging
146+
- Use `DEBUG()` macros liberally
147+
- Check `ASSERT()` failures for logic errors
148+
- Viewer: Use F1 for help dialog, check console output
149+
- Memory issues: Build with `_DEBUG` for additional checks
150+
151+
## Performance Considerations
152+
153+
- Multi-threading via OpenMP (`#pragma omp parallel`)
154+
- CUDA kernels for GPU acceleration (when enabled)
155+
- Memory-mapped files for large datasets
156+
- Spatial data structures (octrees) for efficient queries
157+
- Viewer optimizations: frustum culling, render-only-on-change mode

.github/workflows/continuous_integration.yml

Lines changed: 40 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ jobs:
2323
strategy:
2424
fail-fast: false
2525
matrix:
26-
os: [ubuntu-latest, macOS-latest, windows-latest]
2726
include:
2827
- os: windows-latest
2928
triplet: x64-windows-release
@@ -32,33 +31,45 @@ jobs:
3231
triplet: x64-linux-release
3332
build-type: Release
3433
- os: macos-latest
35-
triplet: x64-osx
34+
triplet: arm64-osx
3635
build-type: Release
36+
env:
37+
# Turn on manifests and binary caching; use the GHA backend
38+
VCPKG_FEATURE_FLAGS: manifests,binarycaching,registries
39+
VCPKG_BINARY_SOURCES: clear;x-gha,readwrite
40+
VCPKG_DEFAULT_TRIPLET: ${{ matrix.triplet }}
41+
VCPKG_COMMIT: 'ef7dbf94b9198bc58f45951adcf1f041fcbc5ea0'
42+
3743
steps:
3844
- name: Checkout
39-
uses: actions/checkout@v3
45+
uses: actions/checkout@v4
4046

41-
- name: Restore artifacts, or setup vcpkg for building artifacts
47+
- name: Setup vcpkg and cache artifacts
4248
uses: lukka/run-vcpkg@v11
4349
with:
44-
vcpkgDirectory: '${{ github.workspace }}/vcpkg'
45-
vcpkgGitCommitId: '4a3c366f2d0d0eaf034bfa649124768df7cfe813'
50+
vcpkgGitCommitId: ${{ env.VCPKG_COMMIT }}
4651

4752
- name: Install Ubuntu dependencies
4853
if: matrix.os == 'ubuntu-latest'
4954
run: |
5055
sudo apt-get update -y
51-
sudo apt-get install -y autoconf-archive libxmu-dev libdbus-1-dev libxtst-dev libxi-dev libxinerama-dev libxcursor-dev xorg-dev libgl-dev libglu1-mesa-dev pkg-config
56+
sudo apt-get install -y autoconf-archive libxmu-dev libdbus-1-dev libxtst-dev libxi-dev libxinerama-dev libxcursor-dev xorg-dev libgl-dev libglu1-mesa-dev autoconf automake bison libtool libltdl-dev pkg-config ninja-build
5257
5358
- name: Install macOS dependencies
54-
if: matrix.os == 'macOS-latest'
59+
if: matrix.os == 'macos-latest'
5560
run: |
56-
brew install automake autoconf-archive
61+
brew install automake autoconf autoconf-archive libtool ninja
5762
58-
- name: Configure CMake
63+
- name: Configure CMake for Windows
64+
if: matrix.os == 'windows-latest'
5965
run: |
6066
cmake -S . -B make -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} -DOpenMVS_USE_CUDA=OFF
6167
68+
- name: Configure CMake for Ubuntu and macOS
69+
if: matrix.os != 'windows-latest'
70+
run: |
71+
cmake -S . -B make -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} -DVCPKG_TARGET_TRIPLET=${{ matrix.triplet }} -DOpenMVS_USE_CUDA=OFF -G Ninja
72+
6273
- name: Build
6374
working-directory: ./make
6475
run: |
@@ -73,9 +84,27 @@ jobs:
7384
7485
- name: Deploy Windows release
7586
if: matrix.os == 'windows-latest'
76-
uses: actions/upload-artifact@v3
87+
uses: actions/upload-artifact@v4
7788
with:
7889
name: OpenMVS_Windows_Release_x64
7990
path: |
8091
${{ github.workspace }}/make/bin/**/x64
8192
!${{ github.workspace }}/make/bin/**/*.exp
93+
94+
- name: Deploy Ubuntu release
95+
if: matrix.os == 'ubuntu-latest'
96+
uses: actions/upload-artifact@v4
97+
with:
98+
name: OpenMVS_Ubuntu_Release_x64
99+
path: |
100+
${{ github.workspace }}/make/bin/**
101+
!${{ github.workspace }}/make/bin/**/*.exp
102+
103+
- name: Deploy macOS release
104+
if: matrix.os == 'macos-latest'
105+
uses: actions/upload-artifact@v4
106+
with:
107+
name: OpenMVS_macOS_Release_arm64
108+
path: |
109+
${{ github.workspace }}/make/bin/**
110+
!${{ github.workspace }}/make/bin/**/*.exp

BUILD.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@ The dependencies can be fetched and built automatically using `vcpkg` on all maj
2626
The latest pre-built stable binaries can be download from [here](https://github.com/cdcseacave/openMVS_sample/releases/latest).
2727

2828
```
29+
#Install necesary system packages, for ex. on Debian OS:
30+
sudo apt install git cmake autoconf autoconf-archive automake libtool bison gfortran pkg-config libxi-dev libx11-dev libxft-dev libxtst-dev libxext-dev libxrandr-dev libxinerama-dev libxcursor-dev xorg-dev libgl-dev libglu1-mesa-dev nasm
31+
2932
#Clone OpenMVS
3033
git clone --recurse-submodules https://github.com/cdcseacave/openMVS.git
3134
@@ -72,7 +75,7 @@ Python API
7275
The Python API can be enable by setting the `OpenMVS_USE_PYTHON` option to `ON` when running `cmake`. The Python API is built as a shared library and can be used in any Python project. Example:
7376
```
7477
import pyOpenMVS
75-
78+
7679
def run_mvs():
7780
# set the working folder; all files used next are relative to this folder (optional)
7881
pyOpenMVS.set_working_folder("folder/containing/the/scene")

0 commit comments

Comments
 (0)