almeshopt
almeshopt 是 meshoptimizer 的 Python 封装(Cython + CMake + scikit-build-core),提供面向 NumPy 的网格索引/顶点重排、渲染性能优化、压缩编解码、简化(LOD)、meshlet 构建等接口。
- 安装:
pip install almeshopt - 导入:
import almeshopt - 实现:优先加载包内扩展模块
almeshopt_avx2(见src/almeshopt/__init__.py)
说明:当前发布策略为 只发布 AVX2 版 wheel(构建时
USE_AVX2=ON)。源码中保留了非 AVX2 的扩展实现入口,但目前不发布对应 wheel。
快速开始
安 装
pip install -U almeshopt numpy
典型用法:简化 + 顶点/索引重排
import numpy as np
import almeshopt
# indices: (N*3,) uint32
# vertices: (V,3) float32,必须 C-contiguous
indices = np.array([0, 1, 2, 2, 3, 0], dtype=np.uint32)
vertices = np.array([[0,0,0],[1,0,0],[1,1,0],[0,1,0]], dtype=np.float32)
# 目标三角形数量(这里演示:减半)
new_indices, error = almeshopt.simplify(
indices,
vertices,
target_count=len(indices)//2,
target_error=1e-2,
)
# 进一步优化:顶点 fetch 重排(返回 new_indices, new_vertices)
opt_indices, opt_vertices = almeshopt.optimize_vertex_fetch(new_indices, vertices)
print(opt_indices.shape, opt_vertices.shape, error)
API 参考(当前仓库实际封装的接口)
下列函数均来自扩展模块(
src/almeshopt/almeshopt.pyx/src/almeshopt/almeshopt_avx2.pyx),导入统一使用import almeshopt。约定:
indices通常为np.uint32的一维数组(长度为三角形数 × 3);vertices通常为二维数组(例如(V, 3)的np.float32)。多数接口要求数组为 C-contiguous。
1)重映射与索引生成
generate_vertex_remap(indices, vertices)→(remap, unique_count)
根据indices+vertices生成顶点重映射表。remap_vertex_buffer(vertices, remap)→new_verticesremap_index_buffer(indices, remap)→new_indicesgenerate_shadow_index_buffer(indices, vertices)→shadow_indicesgenerate_adjacency_index_buffer(indices, vertices)→adjacency_indices(每个三角形 6 个索引)
2)渲染性能优化
optimize_vertex_cache(indices, vertex_count)→new_indicesoptimize_vertex_cache_strip(indices, vertex_count)→new_indicesoptimize_overdraw(indices, vertices, threshold=1.05)→new_indicesoptimize_vertex_fetch(indices, vertices)→(new_indices, new_vertices)
3)压缩与解压(索引/顶点)
encode_index_buffer(indices, vertex_count)→bytesdecode_index_buffer(encoded_data, index_count)→np.ndarray[np.uint32]encode_vertex_buffer(vertices, level=2)→bytes
支持任意 C-contiguous 的 numpy 数组(例如float32/uint16/uint8),level越高压缩率越好但更慢。decode_vertex_buffer(encoded_data, vertex_count, vertex_stride, dtype=np.float32)→np.ndarray
vertex_stride单位是 字节(例如uint16的XYZ0padding,stride=8)。encode_filter_oct(data, bits=8)→np.ndarray[np.uint8]
Octahedral 编码(目前封装为返回字节数组;使用前请确保输入数据形状/stride符合预期)。
4)简化(LOD)
simplify(indices, vertices, target_count, target_error=0.01, sloppy=False, vertex_lock=None, options=0)→(new_indices, error)simplify_with_attributes(indices, vertices, attributes, weights, target_count, target_error=0.01, vertex_lock=None, options=0)→(new_indices, error)simplify_points(vertices, target_count, colors=None, color_weight=1.0)→indices
options 位标志
options 是按位或组合的整数,直接透传给底层的 meshopt_simplify / meshopt_simplifyWithAttributes。
常量已在模块级导出,取值与 extern/meshoptimizer/src/meshoptimizer.h 的 meshopt_SimplifyX 枚举一致:
| 常量 | 值 | 作用 |
|---|---|---|
SIMPLIFY_LOCK_BORDER |
1 << 0 |
不移动位于拓扑边界上的顶点;简化大网格的局部时很有用 |
SIMPLIFY_SPARSE |
1 << 1 |
输入索引只覆盖网格的稀疏子集时提速;注意 error 会变成相对于子集包围盒 |
SIMPLIFY_ERROR_ABSOLUTE |
1 << 2 |
target_error 与返回的 error 按绝对量纲解释,而非相对网格尺度 |
SIMPLIFY_PRUNE |
1 << 3 |
简化过程中增量剔除彼此断开的小块(孤立碎片) |
SIMPLIFY_REGULARIZE |
1 << 4 |
产出更均匀的三角形大小与形状,代价是几何/属性精度略降 |
SIMPLIFY_PERMISSIVE |
1 << 5 |
实验性:允许跨属性不连续处折叠,除非该顶点被标记为 SIMPLIFY_VERTEX_PROTECT |
vertex_lock 数组(uint8,每顶点一个元素)的取值同样已导出:
| 常量 | 值 | 含义 |
|---|---|---|
SIMPLIFY_VERTEX_LOCK |
1 << 0 |
该顶点不允许移动 |
SIMPLIFY_VERTEX_PROTECT |
1 << 1 |
保护该顶点处的属性不连续;必须与 SIMPLIFY_PERMISSIVE 同时使用 |
import almeshopt
# 简化的同时剔除孤立碎片,并锁定边界(适合分块简化大场景)
new_indices, error = almeshopt.simplify(
indices, vertices, target_count,
target_error=0.05,
options=almeshopt.SIMPLIFY_PRUNE | almeshopt.SIMPLIFY_LOCK_BORDER,
)
注意事项:
options=0(默认)与旧版本行为完全一致,不传该参数的既有代码无需改动。sloppy=True走的是meshopt_simplifySloppy,底层没有 options 参数;此时传入非零options会抛ValueError,而不是被静默忽略。- 当前 vendored 的
meshopt_simplify签名里没有vertex_lock参数,因此simplify()的vertex_lock只在sloppy=True时生效。精确简化路径若需要锁顶点,请改用simplify_with_attributes()。 SIMPLIFY_PRUNE只在"常规折叠已经停下、但还没达到target_count"时才会介入。若普通简化本来就能达标,加不加这个标志结果相同。
可运行的演示与自检:demos/simplify_options.py。
5)空间排序
spatial_sort_triangles(indices, vertices)→new_indicesspatial_sort_remap(vertices)→remap
6)分析(统计指标)
analyze_vertex_cache(indices, vertex_count, cache_size=16, warp_size=0, primgroup_size=0)→dictanalyze_overdraw(indices, vertices)→dict
7)Meshlets(Mesh Shading)
build_meshlets(indices, vertices, max_vertices=64, max_triangles=124, cone_weight=0.0)→dict
返回键:meshlets(Nx4)、meshlet_vertices、meshlet_triangles。compute_meshlet_bounds(meshlet_vertices, meshlet_triangles, vertices)→dict
8)Triangle Strip
stripify(indices, vertex_count)→strip_indices
示例(仓库内 demos)
目录:demos/
- 点云压缩(带颜色):
demos/ply_compress.py/demos/ply_decompress.py
主要展示encode_vertex_buffer/decode_vertex_buffer的用法(uint16 几何 + uint8 颜色)。 - GLTF/GLB 简化(带 UV):
demos/mesh_simp_with_texture.py
展示generate_vertex_remap、remap_*、simplify、optimize_vertex_fetch的组合使用。 - 简化 options 位标志:
demos/simplify_options.py
演示并自检SIMPLIFY_*常量、向后兼容性与SIMPLIFY_PRUNE的剔除效果,无外部依赖,直接python demos/simplify_options.py即可运行。
“地形切片 / Cesium Terrain”接口说明
你可能在仓库中看到了 dem_to_cesium_terrain_*.plan.md 之类的规划文档,但当前仓库代码里并没有 TerrainTiler / .terrain 编码器等实现文件(例如 terrain_tiler.py、quantized_mesh.*、terrain_mesher.* 均不存在)。
因此,本包当前对外 API 只包含 meshoptimizer 封装(见上文 API 参考),不包含地形瓦片管线接口。
如果你希望把地形切片管线也纳入 almeshopt 并发布为 wheel,我们可以再按“规划文档 → 实际代码”补齐对应 C++/Cython/Python 层实现与测试。
构建与发布(维护者)
构建 wheel(Windows + Linux manylinux via Docker Desktop)
仓库提供 PowerShell 脚本,目录:scripts/
- 一键构建并上传(默认 cp311/cp312/cp313/cp314;Windows+Linux)
.\scripts\release.ps1
- 只构建 Windows wheel
.\scripts\release.ps1 -Platform windows -SkipUpload
- 只构建 Linux manylinux x86_64(Docker Desktop)
.\scripts\release.ps1 -Platform linux -SkipUpload
- 本机(Visual Studio 2026 + 老版 CMake)构建
系统 CMake 若低于能识别当前 VS generator 的版本(例如 CMake 3.25 最高只认 "Visual Studio 17 2022"), 上面的脚本会在 configure 阶段失败。此时改用 Ninja generator 的专用脚本:
.\scripts\build_wheels_homepc.ps1 -PythonVersions 3.11 -Clean
.\scripts\build_wheels_homepc.ps1 -BuildMode compat # USE_AVX2=OFF
它会用 vswhere 探测 VS 安装路径、导入 VsDevCmd 环境,并强制 CMAKE_GENERATOR=Ninja。
上传到 PyPI
推荐使用环境变量 PYPI_API_TOKEN:
$env:PYPI_API_TOKEN="pypi-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
.\scripts\upload_pypi.ps1 -SkipExisting
中文终端显示:脚本中已包含
chcp 65001+ UTF-8 输出设置,并默认禁用twine进度条以避免 GBK 控制台编码问题。
常见问题(FAQ)
1)为什么 pip install almeshopt 但内部模块叫 almeshopt_avx2?
almeshopt_avx2 是包内部的扩展模块名;对用户而言 安装名与导入名都始终是 almeshopt。almeshopt/__init__.py 会优先加载 AVX2 扩展。
2)数组需要什么 dtype / shape?
不同接口对 dtype/shape 有要求;最通用的组合是:
indices:np.uint32,形状(T*3,)vertices:np.float32,形状(V,3)或拼接属性后的(V, k)并确保np.ascontiguousarray(...)。
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distributions
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file almeshopt-0.1.12-cp314-cp314-win_amd64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp314-cp314-win_amd64.whl
- Upload date:
- Size: 149.8 kB
- Tags: CPython 3.14, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef21f41f06fa7de7f309ca4af38affa11e3ece7cb47dc77e9754b77825d9bde6
|
|
| MD5 |
248505a5cc62f272c30552e40976df74
|
|
| BLAKE2b-256 |
d88c9dd8abc1b0d0332bde5dca3e679b19e887364cf00f5544aa76bda6b14bb8
|
File details
Details for the file almeshopt-0.1.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 319.6 kB
- Tags: CPython 3.14, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5d6f97f85a7e1c65397d4f057e61c70af55c97c35fb432398ebedcdbe0e51aa3
|
|
| MD5 |
53cd01434ad0cf78344c78e3f787ed80
|
|
| BLAKE2b-256 |
779857def384ef85052ab0e43a2231ba5a6b9effae627639e5a8e8c1816aed80
|
File details
Details for the file almeshopt-0.1.12-cp313-cp313-win_amd64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp313-cp313-win_amd64.whl
- Upload date:
- Size: 146.7 kB
- Tags: CPython 3.13, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e36b465cd7854d913711e51a5827896e71f05573ae9a1c0ea3023020c5f2ae93
|
|
| MD5 |
c177f9c62c4fb6e3815907ab384f9f3c
|
|
| BLAKE2b-256 |
e1a61a816d942abf88a359c6c67123dd0c060f923bed067fff0a603fd86cb520
|
File details
Details for the file almeshopt-0.1.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 318.8 kB
- Tags: CPython 3.13, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b5290a6a0dde43fc840fc864ff6838ae2fac500bca8421ec9729f2107c553f5d
|
|
| MD5 |
6565a21712aeac2261f8e911c5d1370a
|
|
| BLAKE2b-256 |
d9169c15863763bccc81fc2a18f677583a03c795002f4497c07ffece72e0cc7d
|
File details
Details for the file almeshopt-0.1.12-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 147.4 kB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c791c4fb47981b22f412c96e35d42dd43c442789e5698c81fbb207a85ec334c4
|
|
| MD5 |
3fd49b71f3a15ad703541fb6ff6debe2
|
|
| BLAKE2b-256 |
2921ce9110c67a685630f7cc2bb6d2fb4a9735c2601914b30f09373af56c09af
|
File details
Details for the file almeshopt-0.1.12-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 319.0 kB
- Tags: CPython 3.12, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e407bbc4421401654c31e6caffc569dc5cf3ff2e4c7465de68c92e0c9bc47962
|
|
| MD5 |
2ba58f6331d43f3301c328903bee4dd6
|
|
| BLAKE2b-256 |
17fa3a8619b40b6a05fff3372706680b1d388d65de7cdc253289dc8128467e38
|
File details
Details for the file almeshopt-0.1.12-cp311-cp311-win_amd64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp311-cp311-win_amd64.whl
- Upload date:
- Size: 148.9 kB
- Tags: CPython 3.11, Windows x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
0dc4ba2d9f1526b365bc84cb5bf9434a87c449883ddf6b7d56aa9efc7585b96b
|
|
| MD5 |
4d27634bd3896ce0ff2ee28272b3d3eb
|
|
| BLAKE2b-256 |
c01d13643e83fa6b2443e34a79e7237c536d4cf2a1e5b83e4415a8560f96a162
|
File details
Details for the file almeshopt-0.1.12-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl.
File metadata
- Download URL: almeshopt-0.1.12-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl
- Upload date:
- Size: 325.1 kB
- Tags: CPython 3.11, manylinux: glibc 2.17+ x86-64, manylinux: glibc 2.28+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/7.0.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
96a6e14abe0b385c6f64124956593e254fcdd8b0b9d76f82137b4da354490bd5
|
|
| MD5 |
c9a784958e9032e53d1ab573cb54bc0e
|
|
| BLAKE2b-256 |
391f2626b65f790a1ab20a9a6f675f6408c7b11021f2f27ce72117bd98f2158a
|