3MF 网格几何编辑工具 cli-anything-3mf 实战指南:圆柱孔检测、改径、网格修复与文件对比

发布时间:2026/9/8 17:12:55
3MF 网格几何编辑工具 cli-anything-3mf 实战指南:圆柱孔检测、改径、网格修复与文件对比 3MF 网格几何编辑工具 cli-anything-3mf 实战指南圆柱孔检测、改径、网格修复与文件对比【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything3MF3D Manufacturing Format正逐步取代 STL 成为 3D 打印生态的主力交换格式——它本质上是“一个 ZIP 包内装着模型 XML 与切层配置”BambuStudio、PrusaSlicer 导出的工程文件都基于它。本文介绍的cli-anything-3mf是 CLI-Anything 生态下的一个 3MF 网格几何编辑 CLI核心能力是自动检测模型中的圆柱孔、把指定孔改到目标直径、修复受损网格并对两个 3MF 文件做结构级对比。读完本文你将掌握该工具全部 5 个命令与选项的真实语义、无损回程如何保留切片器配置的底层原理以及“截面拟合 层次聚类”检测圆柱孔与“径向缩放顶点”改孔的算法细节可直接用于打印前对 BambuStudio/PrusaSlicer 工程文件做参数化修改。这是什么工具3MF 打印前参数化编辑的抓手许多打印前的常见修改——把螺丝孔从 3.2mm 扩到 4.2mm、把某个孔改大以便过轴——如果回建模软件里改完再重新导出会连切片参数一起被冲掉。cli-anything-3mf的定位就是绕过建模软件直接在 3MF 网格几何层做局部参数化修改并把所有非网格内容切片设置、缩略图、板材配置原样打包回去。工具通过 setup.py 声明为 Python 包cli-anything-3mf版本 1.0.0console script 入口指向 threemf_cli.py 的main()因此安装后可直接使用cli-anything-3mf命令也支持python -m cli_anything.threemf见main.py。按 README 说明其主要功能概括为检测并缩放圆柱孔Detect and resize cylindrical holes、修复网格repair meshes、对比 3D 打印文件compare。源码 docstring 进一步将其定义为“3MF CLI — Mesh geometry editor for 3D printing files”。安装与依赖# 直接通过 git 子目录安装 pip install githttps://github.com/HKUDS/CLI-Anything.git#subdirectory3MF/agent-harness # 开发模式安装 cd 3MF/agent-harness pip install -e .[dev]环境要求与依赖以仓库实际为准项要求PythonREADME 标注 3.10setup.py 中python_requires3.9核心依赖numpy1.24.0、scipy1.10.0层次聚类、trimesh4.0.0几何计算/截面/法线修复CLI 依赖click8.0.0命令框架、prompt-toolkit3.0.0REPL 交互dev 扩展pytest7.0.0、pytest-cov4.0.0README 中的 Python 3.10 与 setup.py 的 3.9 略有出入建议按 3.10 使用。值得注意的是utils/threemf_backend.py 与 core/repair.py 在导入时即硬性要求trimesh缺失会直接抛出安装提示因此 trimesh 是运行必需而非可选。命令速览与快速上手安装后所有子命令用法如下来自 README 的 Quick Start# 查看网格信息顶点/面/包围盒/水密性/体积 cli-anything-3mf info model.3mf # 检测圆柱孔输出每个孔的直径、圆心、轴向范围、置信度 cli-anything-3mf inspect model.3mf # 把 0、1、2、3 号孔统一改到 4.2mm 直径 cli-anything-3mf resize model.3mf --hole 0 --hole 1 --hole 2 --hole 3 --diameter 4.2 -o output.3mf # 修复网格问题退化面、重复顶点、孤立顶点 cli-anything-3mf repair model.3mf -o repaired.3mf # 对比两个 3MF 文件 cli-anything-3mf compare original.3mf modified.3mf # 交互式 REPL不带子命令直接运行 cli-anything-3mf命令总表命令描述必填参数info file网格统计顶点数、面数、包围盒、水密性、体积、表面积fileinspect file检测并列出所有圆柱孔含直径与圆心fileresize file将指定孔缩放到目标直径file、--hole可多次、--diameter、-orepair file修复退化面、重复顶点与孤立顶点file、-ocompare f1 f2两个 3MF 文件的并排对比file1、file2全局选项所有命令都支持在命令名前加--json输出机器可读的 JSONcli-anything-3mf --json inspect model.3mf这是给 Agent / 自动化脚本消费的关键特性。一个完整的典型工作流把“inspect → resize → 验证对比”串起来就是最常见的使用链路# 1) 检测孔记下目标孔的 hole_id 与当前直径 cli-anything-3mf --json inspect model.3mf # 2) 把 0、1 号孔改到 4.2mm输出文件默认不允许覆盖已存在文件 cli-anything-3mf resize model.3mf --hole 0 --hole 1 --diameter 4.2 -o resized.3mf # 3) 对比修改前后差异顶点/面数/体积/水密性变化一目了然 cli-anything-3mf compare model.3mf resized.3mf命令详解与全部选项下面逐个命令展开参数语义全部以 threemf_cli.py 的实际实现为准。info —— 网格体检info file解析 3MF 后对每个 mesh object 调用backend.compute_mesh_stats()实现在 utils/threemf_backend.py输出包含文件内对象 id 与 name、顶点数、面数、包围盒min/max 与尺寸、水密性Watertight、体积mm³非水密时显示 N/A、表面积。单位随 3MF 元数据展示如 millimeter。典型输出如下File: model.3mf Unit: millimeter Object 1: bracket Vertices: 1284 Faces: 2560 Bounding box: [-25.00, -20.00, -3.00] to [25.00, 20.00, 12.00] Dimensions: 50.00 x 40.00 x 15.00 mm Watertight: True Volume: 14233.12 mm3 Surface area: 7210.55 mm2其中体积依赖 trimesh 的水密判断is_watertight非水密网格拿不到体积——这也是先repair再评估体积的常见原因。注意文件可能含多个 mesh object输出会逐个列出。inspect —— 圆柱孔检测inspect file是 resize 的前置侦察命令。检测参数齐全时如下选项默认值说明--planes, -n20沿孔轴方向切多少层截面--min-diameter0.5mm小于该直径的孔被忽略--min-confidence0.7低于该置信度0~1的候选被丢弃--axis, -a0孔轴方向0X、1Y、2Z默认按 X 轴扫描--mesh, -m0多对象文件里取第几个 mesh object输出每个孔的 hole_id、直径、圆心坐标垂直于轴的平面内、轴向范围、置信度与参与计算的壁面顶点数。hole_id 是本次检测运行内的序号同一文件换了--axis或--planes再检编号会变这点对 resize 至关重要。resize —— 孔改径cli-anything-3mf resize file --hole id... --diameter mm -o out [--overwrite]参数上--hole-h可重复传多次且必填--diameter-d与--output-o必填--planes、--min-diameter、--min-confidence、--axis、--mesh默认值与 inspect 一致另有--overwrite允许覆盖已存在的输出文件默认输出文件已存在会直接报FileExistsError。CLI 层文档字符串明确给出关键提醒传入的检测参数尤其--axis必须与之前inspect时一致否则 hole_id 对不上。从 modifier.py 的resize_holes()可以看到底层机制resize内部会以你给的参数重新跑一遍inspect_mesh来把 hole_id 解析成几何未知的 hole_id 会抛出 ValueError 并列出实际可用的 id 集。改径成功后 CLI 打印每个孔的old_diameter - new_diameter及移动的顶点数。resize 结束后会自动对该 mesh 执行一次 repair见 threemf_cli.py把径向缩放可能产生的退化面/重复顶点清掉再把报告一并输出。repair —— 网格修复repair file -o out [--overwrite]对指定 mesh object--mesh默认 0执行修复管线输出统计合并的重复顶点数、移除的退化面数、移除的孤立顶点数及修复后顶点/面总数报告键见 repair.py。compare —— 双文件对比compare f1 f2 [--mesh]解析两个文件后对同 index 的 mesh object 做结构化对比实现在 inspector.py 的compare_meshes()输出一张对照表Comparing: original.3mf vs modified.3mf File 1 File 2 Diff ──────────────────────────────────────────────────── Vertices 1284 1340 56 Faces 2560 2676 116 Volume (mm3) 14233.1 13988.4 -244.7 Watertight True True对比维度为顶点数、面数、体积非水密按 0 计与水密性每个字段给出 file1/file2/diff。它是验证“resize/repair 只改了预期的量”最直接的回归手段。交互式 REPL不带子命令直接运行cli-anything-3mf会进入 REPL统一皮肤由 utils/repl_skin.pyReplSkin(3mf, ...)渲染 banner、帮助与错误内部仍把每行输入shlex.split后转发给同一个 Clickclistandalone_modeFalse所以 REPL 内的子命令、选项与命令行完全等价quit/exit/q退出help打印帮助实现见 threemf_cli.py。统一的 JSON 输出与错误处理CLI 有一个全局开关--json命中该开关后所有成功结果以json.dumps(..., indent2)输出失败时则以{error: ..., type: ...}结构化返回见handle_error装饰器与 threemf_cli.py。非 REPL 模式下错误会sys.exit(1)REPL 下则只打印错误继续会话——这套设计让工具既能给人看也适合给 Agent 稳定消费。原理剖析它如何在几何层面工作3MF 解析与无损回程parser3MF 是 ZIP 容器主模型 XML 通常位于3D/3dmodel.model。参考 core/parser.py 的实现解析parse_3mf()先按 ZIP 打开文件优先找3D/3dmodel.model找不到则回退到包内第一个.model随后解析resources/object中的mesh把顶点读成(N,3) float64、三角形索引读成(M,3) int32并提取unit、metadata键值。无损保真除模型 XML 外的所有 ZIP 成员以原始字节存进raw_entries——切片器设置、缩略图、Bambu 配置、OPC 关系文件全都在内write_3mf()重打包时先原样写回这些字节再写入重建的模型 XML。这就是 README 所说“输出文件可在 BambuStudio / PrusaSlicer 打开且不丢配置”的机制来源。属性保留MeshData除网格数组外还带triangle_attributes逐三角形保存pid、p1、p2、p3等非索引属性XML 重建时逐三角形回填保证存活的三角形材质/属性不丢component-only 对象与 component/build 的transform属性按原始 XML 原样保留。命名空间注册 3MF 核心与 Bambu 命名空间前缀避免 ElementTree 序列化时篡改成ns0。README 同时明确该工具当前不应用/编辑 component-instance 变换transform属性原样保留但不会被几何层面处理这是使用上的边界。圆柱孔检测多平面截面 圆拟合 层次聚类README 描述工具在垂直于孔轴的多个平面取截面用最小二乘圆拟合识别圆特征再跨平面聚类出稳定的圆柱孔。对应 inspector.py 的inspect_mesh()与 utils/threemf_backend.py 的cross_section_circles()实际流程分七步沿选定轴默认 X在包围盒内等距放置num_planes默认 20个截面两端各内缩轴跨度的 2%PLANE_INSET_FRACTION避开面边缘的退化切片用 trimeshsection()求每个截面的轮廓离散点把 3D 点投影到垂直于轴的 2D 平面对每段轮廓用Kasa代数最小二乘法拟合圆解超定线性系统x²y²a·xb·yc0得到圆心(-a/2,-b/2)与半径并计算 RMS 拟合误差见 threemf_backend.py。相对拟合误差超过半径 5% 的轮廓视为不够圆直接丢弃用scipy 层次聚类把所有截面上检测到的圆按(center_x, center_y, radius)特征聚类距离阈值_GROUP_DISTANCE_MM 0.5——圆心与半径同时接近才并入同一孔避免“孔壁圆与同一截面的外轮廓同心圆”被错误平均每组求平均直径并结合轴向壁面顶点在组跨度外加一个采样内缩量内搜索真实壁顶点恢复贯穿孔边缘顶点确定轴向范围置信度 该组命中的截面数/总截面数×1 − 平均拟合误差/半径再做内外判定与过滤内外判定通过壁面法向的径向分量区分“真正的内部孔”与“外轮廓/裸圆柱/实体凸台”——孔壁指向空腔法向朝轴心均值 0 判定为 interior从而同时保留通孔与盲孔、剔除外部轮廓见 inspector.py。最终min_diameter默认 0.5mm与min_confidence默认 0.7两层过滤后返回带hole_id/center/diameter/axis_min/axis_max/axis/confidence/vertex_count的DetectedHole列表。孔改径径向缩放保留拓扑与角度对应 modifier.py 的resize_single_hole()选壁顶点对所有顶点计算到孔轴的径向距离选出径向距离与当前半径误差在容差_WALL_RADIUS_TOLERANCE 0.06mm以内、且轴向坐标落在孔范围外扩同容差内的顶点_find_wall_vertices()径向缩放仅修改垂直于孔轴的两个坐标——把选中顶点沿圆心方向线性缩放到target_diameter/2_scale_wall_radially()用scale new_radius / dist逐点缩放轴向坐标不动因此拓扑、角度位置不变只胀大/缩小孔壁。这与 README“Wall vertices are identified by radial distance … scaled radially while preserving mesh topology and angular position”的描述完全对应。实现上注意了两点只处理 2 个垂直轴坐标且对恰好位于圆心的顶点做除零保护。因为缩放会移动顶点索引关系所以 CLI 在 resize 后紧跟自动 repair 收敛网格质量。修复管线四步清理repair.py 的repair_mesh()顺序执行合并重复顶点坐标四舍五入到 6 位小数后用结构化视图做np.unique找规范索引merge_duplicate_vertices()重映射三角形索引到规范顶点移除退化面三角形三条索引存在任意两条相等即视为退化_nondegenerate_face_mask()移除孤立顶点仅保留被任何三角形引用的顶点并压实索引remove_unreferenced_vertices()。每次删除都同步过滤triangle_attributes保证三角形属性与网格数组始终对齐。README 提到“fix normals”对应独立的fix_normals()repair.py它调用trimesh.repair.fix_normals修正法线/winding不过当前repair命令自动流水线默认不包含法线修复需要时可由上层直接调用该函数。代码结构与数据模型导读模块目录见 README Architecture 一节与仓库实际文件3MF/agent-harness/cli_anything/threemf/ ├── threemf_cli.py # Click CLI REPL ├── core/ │ ├── parser.py # 3MF ZIP/XML 解析与无损写回 │ ├── inspector.py # 截面孔检测 / compare │ ├── modifier.py # 孔改径径向缩放 │ └── repair.py # 网格修复管线 ├── utils/ │ ├── threemf_backend.py # trimesh/numpy 几何工具圆拟合、截面、统计 │ └── repl_skin.py # 统一 REPL 皮肤 ├── skills/ │ └── SKILL.md # Agent 可发现的技能声明 └── tests/ └── test_core.py # 单元测试贯穿全模块的是不可变数据模型MeshData单对象网格与ThreeMFData整文件都是 frozen dataclass所有几何函数返回新对象而不改输入backend 模块 docstring 明确“pure”。这种函数式设计让“先 inspect → 再 resize → 自动 repair → 写回”天然安全——每次变换都产生新实例原始数据可随时回溯对比。配套的 skills/SKILL.md 以前置元数据name / description把该 CLI 声明成 Agent 可发现的技能描述中明示“兼容 BambuStudio 与 PrusaSlicer 3MF 文件”README 也在 Agent 生态定位下强调所有命令的--json输出——这正是 “Making software Agent-native” 在 3MF 领域的落地形态。测试与验证单元测试集中在 tests/test_core.py覆盖 parser、backend、inspector、repair、modifier 全部核心模块测试用合成 numpy 数据与内存中生成的 3MF fixture立方体网格等无需外部 3MF 样例文件。开发模式安装后可运行cd 3MF/agent-harness python -m pytest cli_anything/threemf/tests -v使用前提与限制孔检测是按单轴X/Y/Z定向扫描的默认只沿 X 轴方向找圆柱孔斜孔或非轴对齐特征不在能力范围内检测前请用--axis对准实际孔轴hole_id 只在同一检测参数集下有意义resize与inspect的--axis/--planes/...必须一致输出文件默认不覆盖已存在文件脚本化批量处理时记得加--overwrite该工具修改的是网格几何层不会应用 component-instance transform涉及多实例变换的高级编排需在建模软件完成体积等指标依赖水密网格非水密文件建议先repair再评估。整体上cli-anything-3mf把“检测孔、改孔径、修网格、验差异”这条打印前高频链路压缩成了几个可脚本化、可 JSON 化的命令既适合人工在终端快速处理单个工程也适合作为 Agent 工具嵌入自动化打印流水线。【免费下载链接】CLI-AnythingCLI-Anything: Making ALL Software Agent-Native -- CLI-Hub: https://clianything.cc/项目地址: https://gitcode.com/GitHub_Trending/cl/CLI-Anything创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考