Portable checked triangle-surface editing and Loop subdivision
| 任务 | 当前行为 |
|---|---|
| 从三角数组建立可靠连接关系 | 拒绝越界、非有限坐标、重复/退化面、朝向冲突、非流形边和点扇区;支持边界与多个分量 |
| 修改网格后继续使用 | 拆分内部/边界边、翻转合法内部对角线;可恢复检查错误不会留下部分编辑 |
| 让粗三角曲面变平滑 | 原始 Loop 内点权重、内部边 3/8–1/8 规则、边界规则、同步更新旧点、逐层预算和结果 |
| 接回渲染或其他算法 | 导出坐标和索引、重算法线、边界环、拓扑统计;数据所有权与调用方分离 |
git clone https://github.com/ShiChengxu-creater/MoonSurface.git
cd MoonSurface
python tools/check.py --target js
moon run examples/local_edit --target js
moon run examples/loop_refine --target jslocal_edit: V=5 E=8 F=4 chi=1 boundary=4
loop_refine: level=0 V=4 E=6 F=4 chi=2
loop_refine: level=1 V=10 E=24 F=16 chi=2
loop_refine: level=2 V=34 E=96 F=64 chi=2workspace/
moon.work
MoonSurface/ # 此仓库,或实际 moon package ZIP 的解压目录
app/
moon.mod
moon.pkg
main.mbtmembers = [ "./MoonSurface", "./app" ]name = "local/surface_demo"
version = "0.0.0"
import { "ShiChengxu/moonsurface@0.1.0-alpha.1" }import { "ShiChengxu/moonsurface" @surface }
pkgtype(kind: "executable")fn main {
try! {
let mesh = @surface.Mesh::from_indexed(
[
{ x: 0.0, y: 0.0, z: 0.0 },
{ x: 2.0, y: 0.0, z: 0.0 },
{ x: 0.0, y: 2.0, z: 0.0 },
],
[(0, 1, 2)],
)
let result = @surface.subdivide_loop(mesh, 2)
result.mesh.validate()
println(result.mesh.face_count()) // 16
}
}moon build --target js --deny-warn
node tools/moonsurface.mjs examples/data/triangle.json
node tools/moonsurface.mjs examples/data/patch.json --out edited.jsonpython tools/verify.py --target js
python tools/verify.py --target wasm-gc
python tools/verify.py --target nativepub suberror SurfaceError {
InvalidArgument(String)
LimitExceeded(String)
InvalidIndex(Int, Int)
NonFiniteCoordinate(Int)
DegenerateFace(Int)
DuplicateFace(Int)
IsolatedVertex(Int)
InconsistentOrientation(Int, Int)
NonManifoldEdge(Int, Int)
NonManifoldVertex(Int)
InvalidElement(Int)
TopologyInvariant(String)
NumericalFailure(String)
BoundaryEdge(Int)
DuplicateDiagonal(Int, Int)
} derive(Eq, Debug)fn IndexedMesh::new(vertices : Array[Vec3], triangles : Array[(Int, Int, Int)], limits? : Limits) -> IndexedMesh raise SurfaceErrorfn Limits::new(max_vertices? : Int, max_input_faces? : Int, max_output_faces? : Int, max_levels? : Int) -> Limits raise SurfaceErrorpub struct Mesh {
// private fields
}fn Mesh::split_edge(self : Mesh, edge : EdgeId, fraction? : Double) -> SplitReport raise SurfaceErrorInstall
Download zipPortable checked triangle-surface editing and Loop subdivision