ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

fq 解码 STL:用 jq 解析二进制立体光刻(Stereolithography)模型文件

fq 解码 STL:用 jq 解析二进制立体光刻(Stereolithography)模型文件 开发工具CLI【免费下载链接】fqfq - jq for binary formats. Tool, language and decoders for working with binary formats.项目地址https://gitcode.com/gh_mirrors/fq/fq点击查看免费下载fq 是一个面向二进制格式的 jq 风格工具、脚本语言与解码器集合其内置的stl解码器用于解析二进制 STLStereolithography / Standard Tessellation Language立体光刻/标准曲面细分语言文件把原本不可读的三角形网格数据映射为结构化 JSON从而可以直接用 jq 查询模型的面片数量、顶点坐标、法向量等几何信息。本文围绕 format/stl/stl.md 展开结合 stl.go 的源码实现与 file.stl.fqtest 测试样例完整讲解二进制 STL 的布局、fq 的字段映射方式、实际解码输出与当前已知限制读完即可上手分析任意二进制 STL 文件。STL 格式背景与二进制布局STL 是 3D 打印与 CAD/CAM 领域最常用的三角网格交换格式之一它把模型表面描述为一系列互不相交的三角形facet。格式分为 ASCII 与二进制两种变体本文讨论的 fq 解码器只针对二进制变体。一个标准二进制 STL 文件由三部分组成偏移长度内容080 字节文件头header通常为 ASCII 文本例如Exported from Blender-3.6.23804 字节面片数量num_facetsuint32小端8450 × N 字节N 个三角形面片每个固定 50 字节每个三角形面片固定为 50 字节内部结构为偏移长度内容012 字节法向量normal3 个 float32x/y/z1236 字节三个顶点vertices每个顶点 3 个 float32x/y/z482 字节attribute_byte_countuint16通常为 0表示其后跟随后续属性数据的字节数fq 中 STL 解码器的注册与入口在 fq 中每个格式都以decode.Group的形式登记在 format/format.goSTL decode.Group{Name: stl}随后在 format/stl/stl.go 中通过interp.RegisterFormat把stl组名、描述字符串Standard Tessellation Language与解码函数decodeSTL绑定同时用interp.RegisterFS注册内嵌的stl.md文档使得用户在交互式 REPL 中输入:help stl之类指令时能看到格式说明func init() { interp.RegisterFormat( format.STL, decode.Format{ Description: Standard Tessellation Language, DecodeFn: decodeSTL, }) interp.RegisterFS(stlFS) }入口函数decodeSTL首先把解码器端序切换为小端然后调用decodeSTLModelfunc decodeSTL(d *decode.D) any { d.Endian decode.LittleEndian decodeSTLModel(d) return nil }由于 STL 二进制格式全部使用 IEEE 754 小端 float32 与 uint32/uint16这里强制LittleEndian是正确且必要的——它保证后续所有FieldF32/FieldU32读取都按二进制 STL 规范的字节序解释。字段映射从字节到结构化 JSONdecodeSTLModel是核心解码逻辑对应 STL 文件的三段式布局func decodeSTLModel(d *decode.D) { d.FieldUTF8NullFixedLen(header, headerLength) numFacets : d.FieldU32(num_facets) d.FieldStructNArray(facets, facet, int64(numFacets), decodeFacet) }header调用 FieldUTF8NullFixedLen 读取固定 80 字节并以 NUL 结尾截断的 UTF-8 字符串headerLength常量定义为 80见 stl.go。许多建模软件会把导出工具与版本号写入此处例如测试样例中的Exported from Blender-3.6.23。num_facets用FieldU32读取 4 字节小端无符号整数作为后续面片数组的长度。facets通过FieldStructNArray按num_facets重复解码decodeFacet每个元素在输出中的结构名structName为facet从而在 JSON 中呈现为facets[0]、facets[1]… 每个 facet 都带facet标签。单个面片的解码由decodeFacet完成func decodeFacet(d *decode.D) { d.FieldStruct(normal, decodeVector) d.FieldStructNArray(vertices, vertex, 3, decodeVector) attributeByteCount : d.FieldU16(attribute_byte_count) if attributeByteCount 0 { d.FieldRawLen(attribute, int64(attributeByteCount)*8) } }normal一个由decodeVector定义的结构体包含 x/y/z 三个字段。vertices固定 3 个vertex结构体的数组。attribute_byte_count2 字节 uint16。多数文件为 0若大于 0解码器会用 FieldRawLen 以位为单位字节数 × 8把剩余属性原始数据整体读入attribute字段而不是丢弃从而保证解码后的字节范围与实际文件完全对齐。decodeVector定义了三元组坐标的通用读取方式三个字段均为FieldF32pkg/decode/decode_gen.go#L18293读取当前端序下的 32 位 IEEE 754 浮点数func decodeVector(d *decode.D) { d.FieldF32(x) d.FieldF32(y) d.FieldF32(z) }由此任意二进制 STL 文件会被解码成如下结构的 JSON 树{ header: Exported from Blender-3.6.23, num_facets: 4, facets: [ { normal: { x: 0, y: -1, z: 0 }, vertices: [ { x: 1, y: 0, z: 0 }, { x: 0, y: 0, z: 1 }, { x: 0, y: 0, z: 0 } ], attribute_byte_count: 0 } ] }实际解码输出验证仓库在 format/stl/testdata/file.stl.fqtest 中提供了完整的解码期望输出对应一个由 Blender 3.6 导出的、包含 4 个面片的 284 字节 STL 文件。其顶层摘要为$ fq -d stl dv file.stl .{}: file.stl (stl) 0x0-0x11c (284) header: Exported from Blender-3.6.23 0x0-0x50 (80) num_facets: 4 0x50-0x54 (4) facets[0:4]: 0x54-0x11c (200)可以看到 fq 的十六进制与反汇编视图会为每个字段标注精确的字节区间header 占0x0-0x5080 字节num_facets占0x50-0x544 个面片恰好覆盖文件剩余0x54-0x11c4 × 50 200 字节与二进制 STL 布局完全一致。面片内部也逐字段给出坐标值与偏移例如第一个面片的法向量normal{}: 0x54-0x60 (12) x: 0 0x54-0x58 (4) y: -1 0x58-0x5c (4) z: 0 0x5c-0x60 (4) vertices[0:3]: 0x60-0x84 (36) [0]{}: vertex 0x60-0x6c (12) x: 1 0x60-0x64 (4) y: 0 0x64-0x68 (4) z: 0 0x68-0x6c (4) attribute_byte_count: 0 0x84-0x86 (2)字节区间的总和12 36 2 50 字节精确等于一个 facet 的标准长度。值得注意的是第 4 个面片展示了浮点坐标的原始精度x: 0.5773502588272095 0xea-0xee (4)0.5773502588272095是 1/√3 的 float32 近似值STL 中常见于对角线方向的单位法向量fq 保留完整的 IEEE 754 解析结果而非四舍五入便于后续做精确的几何校验。使用方式命令行与 jq 查询编译安装 fq 后可直接用-d stl指定解码器解析 STL 文件。常用命令示例# 查看整体结构与字节偏移ddisplayvverbose fq -d stl dv model.stl # 输出为 JSON配合 jq 查询几何信息 fq -d stl tojson model.stl # 统计面片数量 fq -d stl tojson model.stl | jq .num_facets # 查看所有面片的法向量 fq -d stl tojson model.stl | jq .facets[].normal # 提取第一个顶点的坐标 fq -d stl tojson model.stl | jq .facets[0].vertices[0] # 找出坐标最大/最小边界包围盒估算 fq -d stl tojson model.stl | jq [.facets[].vertices[] | .x] | {min: min, max: max}由于 facets 是定长结构数组jq 的管道、映射与聚合能力可以直接作用于网格数据这让统计三角形数量、检查法向量是否单位化、计算模型包围盒、验证网格水密性等分析任务都可以在命令行一步完成无需编写解析脚本。当前限制与注意事项根据 format/stl/stl.md 的说明fq 的 STL 解码器目前存在以下限制分析文件时需要留意不支持 ASCII STL 文件decodeSTL只按二进制布局80 字节头 uint32 面片数解析遇到以solid开头的 ASCII STL 会被当作二进制头处理得到错误的num_facets。使用前需确认文件为二进制变体。不支持 VisCAM 和 SolidView 颜色这两款软件把颜色信息编码在attribute_byte_count之后的 2 字节属性中。源码在 stl.go 以// TODO support color of VisCAM and SolidView注明尚未实现。不支持 Materialise Magics 颜色Materialise Magics 把整个模型以一个 facet 颜色数据的变体格式存储同样在 stl.go 与 stl.go 处以 TODO 标注尚未支持。好消息是即使attribute_byte_count 0fq 仍会把属性字节原样读入attribute字段FieldRawLen逻辑因此带 VisCAM/Materialise 颜色扩展的文件虽无法解析出语义化的颜色但结构依然能够完整解码、字节不会错位用户仍可对几何数据部分进行 jq 分析。结合源码进一步扩展对于希望把 STL 能力接入其他格式或自定义脚本的读者可以从以下几处继续深入当前仓库format/stl/stl.go完整的 STL 解码实现约 60 行是理解 fq 格式插件最精简的范例之一注册、内嵌文档、小端切换、结构体数组递归解码一应俱全。format/format.goformat.STL组的定义位置可参照其模式在 fq 中登记自定义格式。format/stl/testdata/file.stl.fqtestfq 的回归测试样例展示了逐字节的期望解码结果也是理解fq -d stl dv输出格式的最佳参考。pkg/decode/decode_gen.go、pkg/decode/decode_gen.goFieldUTF8NullFixedLen、FieldRawLen、FieldF32等基础读取原语的定义可用于推断其他二进制格式解码器的工作原理。从源码结构看STL 解码器完全由通用的 decode 原语组合而成没有依赖任何第三方库若未来要支持 ASCII STL最自然的做法是在decodeSTL入口先读取并判断头 5 个字节是否为solid关键字再分流到两条解析路径但这一能力在当前仓库中尚未实现。赞分享开发工具CLI【免费下载链接】fqfq - jq for binary formats. Tool, language and decoders for working with binary formats.项目地址https://gitcode.com/gh_mirrors/fq/fq点击查看免费下载相关推荐用 fq 解析 TZX 磁带格式ZX Spectrum 二进制格式的 jq 式结构化解码用 fq 解析 TZX 磁带格式ZX Spectrum 二进制格式的 jq 式结构化解码 TZX 是专为保存 ZX Spectrum 等 8 位家用计算机盒式开发工具CLIfq 的 bits / bytes 格式用 jq 对二进制位与字节进行切片、索引与解码fq 的 bits / bytes 格式用 jq 对二进制位与字节进行切片、索引与解码 本文讲解 fq 内置的 bits 原始位与 bytes 原始字节开发工具CLINginx流量监控终极指南10分钟搭建专业级监控系统Nginx流量监控终极指南10分钟搭建专业级监控系统 Nginx module vts是一款功能强大的Nginx虚拟主机流量状态监控模块能够帮助用户实时监控后端可观测性指标监控上一篇如何快速上手多臂机器人协同控制基于 LeRobot 的新手完整指南下一篇Handsontable 15.x 版本演进全解析主题系统、CSV 注入防护与稳定性修复创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表