Convert, view, inspect, and split lidar point cloud files. Mesh output supports both visualization (smooth, watertight) and precision (geometrically faithful) workflows.
- Input formats: LAS, LAZ, E57, PLY, PCD, XYZ, PTX, PTS
- Output formats: OBJ, glTF, GLB, STL
- Interactive 3D viewer with per-scan coloring (E57)
- Metadata inspection, per-scan splitting
- Interruptible pipeline — Ctrl+C exits immediately even during Open3D C++ calls
- Animated progress bar during long stages
Requires Python 3.10 – 3.12. Open3D does not yet ship wheels for Python
3.13, and numpy is pinned to <2 for Open3D ABI compatibility.
git clone https://github.com/larsenTFG/scan2mesh.git
cd scan2mesh
pip install -e .
# Optional: E57 support (requires C++ build tools on first install)
pip install -e ".[e57]"Sample E57 files are available in examples/ to try out the tool.
scan2mesh has four subcommands. The convert command is the default — it can
be omitted from the command line.
| Command | Purpose |
|---|---|
convert |
Point cloud → mesh (default) |
view |
Open an interactive 3D viewer |
inspect |
Show file / per-scan metadata |
split |
Split an E57 file into per-scan files |
Run any command with --help for the full option list.
Convert a point cloud file to a mesh.
scan2mesh convert <input> <output>
scan2mesh <input> <output> # 'convert' is implicitConvert runs in one of two reconstruction modes, each with three quality presets:
Smooth, watertight meshes for viewers, web, and game engines. Uses Poisson reconstruction, which fills gaps and produces render-ready surfaces.
Options
| Flag | Description | Default |
|---|---|---|
-q, --quality {low,medium,high} |
Preset within the mode. | medium |
-f, --target-faces INT |
Cap the output triangle count. | Preset |
--poisson-depth INT |
Poisson octree depth. | Auto (scene-scaled) |
--voxel-size FLOAT |
Absolute voxel size. | Auto |
--color / --no-color |
Vertex color transfer. | --color |
Presets
| Preset | Voxel (× spacing) | Poisson depth floor | Target faces |
|---|---|---|---|
low |
8× | 7 | 500K |
medium |
4× | 9 | 2M |
high |
2× | 10 | Unlimited |
Examples
# Quick preview
scan2mesh examples/trimble.e57 preview.glb -q low
# Web-ready mesh with a fixed polygon budget
scan2mesh examples/pump.e57 pump.glb -q medium -f 250000Geometrically faithful meshes — only triangulates where points were actually measured. Uses Ball Pivoting, which leaves real gaps as holes rather than hallucinating surface.
Options
| Flag | Description | Default |
|---|---|---|
-q, --quality {low,medium,high} |
Preset within the mode. | medium |
--max-deviation FLOAT |
Max mesh deviation from source (mm). | Preset |
--bpa-radii "a,b,c" |
Ball Pivoting radii as multiples of point spacing. More/larger values bridge more gaps at the cost of runtime. | 1,2,4 |
--voxel-size FLOAT |
Absolute voxel size. | Auto |
--color / --no-color |
Vertex color transfer. | --no-color |
Presets
| Preset | Voxel (× spacing) | Normal neighbors | Decimation |
|---|---|---|---|
low |
3× | 30 | ≤ 5 mm deviation |
medium |
1.5× | 50 | ≤ 2 mm deviation |
high |
1× (dedupe only) | 50 | None |
Examples
# Keep every measured point, transfer scanner colors
scan2mesh examples/pump.e57 pump.glb --mode precision -q high --color -v
# Tight deviation budget for QA / metrology
scan2mesh input.e57 out.obj --mode precision --max-deviation 1.0
# Extend BPA radii to bridge sparse scan regions
scan2mesh input.e57 out.glb --mode precision -q high --bpa-radii 1,2,4,8 --color| Flag | Description |
|---|---|
--method {poisson,ball_pivoting} |
Override reconstruction algorithm (decouples from mode default). |
--scans "0,2,3" |
For E57: include only these scan indices. |
--no-outlier-removal |
Skip the outlier filter (faster; safe for clean scans). |
-v, --verbose |
Per-stage logs including live elapsed time. |
Open an interactive 3D viewer for a point cloud file.
scan2mesh view <input>Uses Open3D's visualizer. For multi-scan E57 files, scans can be coloured and isolated at runtime.
Options
| Flag | Description | Default |
|---|---|---|
--voxel-size FLOAT |
Downsample before display (handy for huge clouds). | No downsampling |
--background {dark,light} |
Viewer background color. | dark |
Keybindings (E57 with multiple scans)
| Key | Action |
|---|---|
S |
Color points by scan index |
1–9 |
Isolate an individual scan |
Examples
# View the whole file
scan2mesh view examples/trimble.e57
# Downsample a huge cloud before displaying
scan2mesh view cloud.ply --voxel-size 0.05
# Light-background view
scan2mesh view large_scan.las --background lightShow metadata about a point cloud file without loading it fully into a mesh pipeline.
scan2mesh inspect <input>For E57 files, prints a table with per-scan point count, available fields (x/y/z, intensity, color), and bounding box. For other formats, shows basic point cloud statistics (count, bounds, has-colors, has-normals).
Examples
scan2mesh inspect examples/pump.e57
scan2mesh inspect cloud.plyUse this first on unfamiliar E57 files so you know what --scans selectors
to pass to convert or split.
Split an E57 file into individual per-scan files.
scan2mesh split <input.e57> <output_dir>Each scan is written as a separate point cloud. Useful when a multi-scan E57 needs to be processed scan-by-scan or fed to a tool that can't read E57.
Options
| Flag | Description | Default |
|---|---|---|
--format {ply,pcd,las} |
Output format for each scan file. | ply |
--scans "0,2,3" |
Only export these scan indices. | All |
Examples
# Split every scan into PLY files
scan2mesh split examples/pump.e57 ./pump_scans/
# Only scans 0, 2, 3 — as PCD
scan2mesh split building.e57 ./scans/ --format pcd --scans 0,2,3Currently only E57 input is supported (no other format stores independent scans).
- Read — format-specific reader → unified point cloud
- Estimate spacing — k-NN sample to size voxels and reconstruction radii from the scene's native resolution
- Downsample — voxel-grid (skippable in some presets)
- Outlier removal — radius-based when spacing is known, statistical
otherwise (skippable via
--no-outlier-removal) - Normal estimation — fast viewpoint flip (BPA) or consistent MST orientation (Poisson)
- Surface reconstruction — Poisson or Ball Pivoting
- Post-process — decimation (face-count or deviation) + vertex color transfer
- Export — OBJ / GLB / glTF / STL
- Huge clouds + precision/high: the pipeline auto-bumps
voxel_sizeif the post-downsample count would exceed the Ball Pivoting practical limit (~1.5M points). Watch for theWARNING: Ball Pivoting input ... bumping voxel_sizeline in-vmode. - Holes with BPA? Extend radii:
--bpa-radii 1,2,4,8, or switch to--mode visualizationto fill gaps with Poisson. - Ctrl+C works at any stage — blocking calls run in daemon threads.
pip install -e ".[dev]"
pytest tests/MIT — see LICENSE.