A ground-up rewrite of MeshLab, the open source system for processing and editing large 3D triangular meshes and point clouds. QMeshLab is a single-document, multi-view Qt 6 application built on QRhi (Metal, Vulkan, Direct3D 12), vcglib, and a plugin architecture for I/O and filters, with optional embedded Python bindings through nanobind.
Status: in active development, before the first tagged release. The user interface and the Python API are still moving. Signed macOS and portable Windows builds are produced by CI — see GitHub Actions: macOS DMG below.
- Python Scripting
- Architecture
- Data Model
- Rendering
- Adding a Filter
- Vocabulary
- Filter Organization
- Filter Classification
- Filter Names
- Preferences
- Memory Accounting
- Usage Statistics
- LLM Integration
- Single
Documentshared by one or moreRenderWidgetviews - Split-view UI (horizontal/vertical), active-view indicator, dual tree/table layer dock, log/filter docks, undo graph, and optional Python console dock
- Per-view mode switching between
3D Scene,Parametrization (UV)(when the current mesh has UVs), andRaster(when the active layer is a raster) - Interactive tool framework with layer picking, rubber-band selection, surface measuring, and layer transforms; tools are pinned to their owner view, can be suspended with
Tabfor camera navigation, and commit durable edits through filters for undo/script history - Scene overlays for selection, normals, boundaries, texture seams, non-manifold markers, curvature directions, current-mesh outline, trackball/light/axis gizmos, tool guides, quality histogram, and optional decorator info counts
- PBR fill with albedo/normal/occlusion/roughness maps, tangent-space or object-space normal-map interpretation, plus Radiance Scaling
- Scene3D rendering organized as lightweight
RenderFrameRequestpass requests -> GPU resource preparation -> concreteRenderFramePlandraw items -> pass executors - Fill rendering modes (
Plain,Pbr,RadianceScaling) isolated behind material renderers with shared fill services and an RS pre-pass hook - Fat-edge rendering for edge meshes and decorator boundaries/seams/non-manifold edges (configurable width)
- UV mode support for boundary-edge, texture-seam, and selection overlays on the current mesh; rubber-band selection can operate in UV space, while UV rendering remains a separate renderer with convergence toward the Scene3D material path planned next
- Raster mode displays the current raster as the view reference with aspect-preserving fit, pan/zoom navigation, and opacity control; rasters with camera shots reuse the Scene3D mesh pass pipeline through the raster camera
- Versioned camera/render-state JSON supports copy/paste, capture/apply, active-view snapshots, and headless offscreen snapshot workflows; concrete GPU
RenderFramePlanobjects remain internal and are not serialized - Plugin-based mesh import/export with per-extension preferred import plugin, plus direct MeshLab project (
.mlp) loading and saving for mesh/raster layer sets - Plugin-based filter framework with searchable category tree, generated parameter dialogs,
pythonNamemetadata, structured provenance/references, markdown descriptions, default reset, and compact/full Python call generation - Filter parameters include mesh, texture, point/vector, camera-state, and render-state values; parameter panels can reset to descriptor defaults and source state JSON from the active view
- Raster projection filters can transfer current/all visible raster colors to vertex colors or bake visible rasters into a mesh texture atlas using existing wedge UVs
- Remeshing filters include layer-aware mesh parameters such as an alternate reference surface for isotropic remeshing reprojection/distance checks
- Embedded Python bindings when
QMESHLAB_PYTHON_CONSOLE=ON; the in-app Python dock exposes the live document asms, the live view helper asmlgui, and the public standalone facade aspymeshlab2 - Tree-shaped undo/redo integrated with mesh operations, filter runs, selection-delta storage, camera/render-style snapshots, script-action history, branch pruning/linearization, and opt-in byte-budget/system-pressure purging
- Structured logging for app/VCG/error messages, load/filter progress, GPU buffer rebuild timing, and automatic undo-prune events;
Help > Memory Infoseparates OS footprint, tracked CPU ownership, and logical GPU-cache sizes and can copy exact JSON for external profiling - PNG snapshot export from the active view (custom resolution + embedded camera/trackball JSON metadata), plus snapshot-to-raster workflows
Built-in I/O plugin families (dependency-gated at build time):
io_vcg(ply,obj,stl,off,vmi)io_obj_rapidobj(obj)io_3mf(3mf)io_gltf(gltf,glb)io_e57(e57, optional)io_trueform(obj,stl, optional)
MeshLab project files (.mlp) are loaded and saved directly by Document, combining mesh plugin I/O, mesh transforms, raster planes, and raster camera shots.
Built-in filter plugins (dependency-gated at build time). A plugin is a dependency/build unit, not a user-facing grouping — the Filters menu is organized by filter category instead, see Vocabulary:
filter_basicfilter_camerafilter_cgalfilter_cleanfilter_color_projectionfilter_colorprocfilter_createfilter_embreefilter_expressionfilter_geodesicfilter_icpfilter_iglfilter_img_patch_paramfilter_instant_meshesfilter_layerfilter_measurefilter_meshfixfilter_meshingfilter_mlsfilter_plymcfilter_quadwildfilter_qslimfilter_samplingfilter_screened_poissonfilter_selectfilter_texturefilter_texture_defragmentationfilter_trioptimizefilter_trueformfilter_unsharpfilter_vertex_displacementfilter_voronoifilter_xatlas
Prerequisites:
- Qt 6.11+ with Qt SVG
- CMake 3.25+
- Build tool:
ninjaormake - vcpkg clone
- Python development libraries when
QMESHLAB_PYTHON_CONSOLE=ON(default)
This repository contains vcpkg.json; non-Qt dependencies are installed via vcpkg manifest mode.
Qt6 and Python are intentionally kept outside vcpkg. vcglib, selected
algorithm archives such as MeshFix and QSlim, and the math-only JKQTMathText
dependency are git submodules. nanobind is provided through vcpkg and is used
for the private _qmeshlab extension behind the embedded pymeshlab2 facade.
The dependencies listed in vcpkg.json (for example rapidobj, draco, libigl, etc.) are installed automatically using vcpkg's manifest mode. After bootstrapping vcpkg, simply run the following command to install all required dependencies:
vcpkg install --triplet x64-windowsThis will ensure all non-Qt dependencies are set up correctly. Qt6 remains outside of vcpkg and must be installed separately.
git submodule update --init --recursive
git clone https://github.com/microsoft/vcpkg ./vcpkg
./vcpkg/bootstrap-vcpkg.shIf your vcpkg is elsewhere, set:
export VCPKG_ROOT="/absolute/path/to/vcpkg"Release:
cmake --preset vcpkg-release
cmake --build --preset vcpkg-release -j8
./build-release/QMeshLabDebug:
cmake --preset vcpkg-debug
cmake --build --preset vcpkg-debug -j8
./build-debug/QMeshLabNotes:
vcpkg-debugandvcpkg-releaseare defined inCMakeUserPresets.json.- They use
Unix Makefilesand setVCPKG_ROOT=${sourceDir}/vcpkgexplicitly, which helps in GUI environments (for example VS Code) where shell environment variables are not always inherited.
CMake: Select Configure Preset-> choosevcpkg-debugorvcpkg-release.CMake: ConfigureCMake: Build- Launch with the CMake Tools run/debug actions.
If presets were changed and VS Code still uses stale values:
CMake: Delete Cache and ReconfigureDeveloper: Reload Window
git submodule update --init --recursive
cmake --preset local-no-vcpkg
cmake --build --preset local-no-vcpkg
./build-local/QMeshLabThe local minimal preset disables dependency-heavy plugins (io_gltf, io_e57, io_obj_rapidobj). Because the embedded Python console is enabled by default, this path still needs local Python development files and nanobind. If you want a lean viewer-only build without those, configure with -DQMESHLAB_PYTHON_CONSOLE=OFF.
LaTeX rendering in filter help can likewise be disabled with
-DQMESHLAB_MATH_HELP=OFF.
The repository includes a manual GitHub Actions workflow at
.github/workflows/macos-dmg.yml that builds, signs, and notarizes an Apple
Silicon macOS .dmg.
What it does:
- checks out the repo with submodules
- installs the build tools,
libomp, and the GNU autotools needed by vcpkg - installs Qt 6.11 with
install-qt-action - reuses the action cache for Qt downloads/install files when available
- bootstraps local
vcpkg - configures a
Releasebuild from the trackedvcpkg-manifestpreset - generates a proper macOS
.icnsfrom the MeshLab app icon and embeds it in the app bundle - bundles
libomp.dylibinto the app when OpenMP-linked plugins are present - applies the same icon to the mounted DMG volume when the runner provides
SetFile - signs the app, frameworks, and plugins with a Developer ID Application certificate
- enables hardened runtime and secure timestamps
- submits the DMG to Apple's notary service, staples the ticket, and verifies it
- uploads the signed and notarized DMG as
QMeshLab-YYYY-MM-DD-<short-sha>-macos-arm64.dmg
Required repository secrets:
MACOS_CERTIFICATE_P12: the base64-encoded.p12containing the Developer ID Application certificate and its private keyMACOS_CERTIFICATE_PASSWORD: the password used when exporting that.p12APPLE_API_KEY_ID: the App Store Connect API key IDAPPLE_API_ISSUER_ID: the App Store Connect API issuer IDAPPLE_API_PRIVATE_KEY: the complete.p8private key, including itsBEGIN PRIVATE KEYandEND PRIVATE KEYlines
Create a Developer ID Application certificate in the Apple Developer portal,
install it in Keychain Access, and export the certificate together with its private
key as a password-protected .p12. On macOS, its secret value can be prepared with
base64 -i DeveloperID.p12 | pbcopy. Create the notarization API key under App
Store Connect's Users and Access > Integrations section. The .p8 file can be
downloaded only once, so keep the original in a secure location.
How to use it:
- Open the
Actionstab on GitHub - Select
macOS DMG - Click
Run workflow - Download the
QMeshLab-YYYY-MM-DD-<short-sha>-macos-arm64artifact from the completed run
The workflow runs on macos-15, producing an arm64 application. The resulting DMG
therefore requires an Apple Silicon Mac: Rosetta does not help here, so Intel Macs are
not covered by a prebuilt package and have to build from source. The packaging
script still produces an ad-hoc signed DMG when used locally without
--sign-identity; notarization is performed only by the GitHub Actions workflow.
The repository also includes a manual GitHub Actions workflow at
.github/workflows/windows-portable.yml that builds a portable Windows .zip.
What it does:
- checks out the repo with submodules
- sets up MSVC on
windows-2022 - installs Qt 6.11 from the public
download.qt.iopackage archives and caches the local Qt SDK directory - bootstraps local
vcpkg - installs vcpkg dependencies in a separate manifest step before CMake configure
- uses a custom release-only Windows vcpkg triplet so CI does not build debug dependency variants too
- configures and builds a release build with the
vcpkg-manifestpreset - runs
windeployqtonQMeshLab.exe - copies additional runtime
.dllfiles from the release-only manifestvcpkg_installed/<triplet>/bin - archives the deploy directory as
QMeshLab-YYYY-MM-DD-<short-sha>-windows-x86_64.zip - uploads the generated
.zipas a workflow artifact
How to use it:
- Open the
Actionstab on GitHub - Select
Windows Portable - Click
Run workflow - Download the
QMeshLab-YYYY-MM-DD-<short-sha>-windows-x86_64artifact from the completed run
Current status:
- packaging is portable
.zip, not an installer - the workflow targets
x64onwindows-2022 - code signing can be added later if you want a more polished distribution path
To build on Windows you need:
- Visual Studio 2022 with the Desktop C++ workload.
- CMake 3.25+.
- Git.
- Qt 6.11.
- A local vcpkg checkout.
Setup steps:
git submodule update --init --recursive
git clone https://github.com/microsoft/vcpkg .\vcpkg
.\vcpkg\bootstrap-vcpkg.bat
$env:VCPKG_ROOT = (Resolve-Path .\vcpkg)
cmake --preset default
cmake --build --preset defaultNotes:
- The
defaultpreset uses vcpkg manifest mode throughVCPKG_ROOT. - Packages from
vcpkg.jsonsuch asdraco,rapidobj,tinygltf,libe57format,xerces-c,muparser,embree,nanobind,cgal, andlibiglare resolved automatically during configure. Do not install them manually. - Qt stays outside vcpkg and must be installed separately.