iamahsanmehmood/openskp
GitHub: iamahsanmehmood/openskp
OpenSKP 是一个基于逆向工程的开源 SketchUp .skp 文件解析器,让开发者无需 SketchUp 或其 SDK 即可通过纯代码提取模型数据。
Stars: 0 | Forks: 0
# 🏗️ OpenSKP
### 开源 SketchUp 文件解析器
**无需 SketchUp 即可解析 `.skp` 文件。无需 SDK。无需许可证。仅需代码。**
[](https://opensource.org/licenses/MIT)
[](https://python.org)
[](#platform-support)
[](https://github.com/iamahsanmehmood/openskp)
*适用于 Python、TypeScript 和 Dart 的开源 SketchUp 二进制文件解析器*
[快速开始](#-quick-start) · [功能](#-features) · [文档](#-documentation) · [贡献](#-contributing)
## 🌟 什么是 OpenSKP?
OpenSKP 是**第一个也是唯一一个**针对 SketchUp (`.skp`) 二进制文件的开源、跨平台解析器。它完全通过对 SketchUp 2021+ 中使用的专有 **VFF 二进制格式**进行逆向工程构建而成,让你能够完全以编程方式访问 3D 模型——包括几何体、材质、组件、图层等——而无需依赖 SketchUp 应用程序或其专有的 SDK。
## ✨ 功能
| 功能 | 状态 | 描述 |
|:--------|:------:|:------------|
| **解析 SKP 2021+** | ✅ | 完整支持 VFF (SketchUp 2021+) 二进制格式 |
| **3D 几何体提取** | ✅ | 顶点、边、面、法线和 UV 坐标 |
| **组件层级** | ✅ | 嵌套的组件定义和实例变换 |
| **图层 / 标签** | ✅ | 带有颜色和可见性状态的图层定义 |
| **材质与纹理** | ✅ | 材质属性、颜色和嵌入的纹理图像 |
| **动态组件** | ✅ | 提取动态组件的属性键值对 |
| **导出为 GLB** | ✅ | 具有完整场景图的行业标准 glTF Binary 导出 |
| **导出为 OBJ** | ✅ | 支持 MTL 材质的 Wavefront OBJ 导出 |
| **导出为 JSON** | ✅ | 以结构化 JSON 形式提供完整的模型数据 |
| **纯实现** | ✅ | 无需 SketchUp SDK,无原生依赖,无需许可证 |
| **跨平台** | ✅ | 适用于 Linux、macOS 和 Windows |
## 🖥️ 平台支持
| 平台 | 版本 | 状态 | 安装 |
|:---------|:--------|:------:|:--------|
| 🐍 **Python** | `v0.1.0` | ✅ 可用 | `pip install openskp` |
| 📘 **TypeScript** | — | 🚧 开发中 | 即将推出 |
| 🎯 **Dart** | — | 🗓️ 已规划 | 已在路线图上 |
## 🚀 快速开始
### 安装
```
pip install openskp
```
### 解析 SketchUp 文件
```
from openskp import SkpFile
# 打开并解析 SKP 文件
model = SkpFile.open("my_model.skp")
# 访问几何体
for face in model.faces:
print(f"Face with {len(face.vertices)} vertices")
for vertex in face.vertices:
print(f" ({vertex.x:.2f}, {vertex.y:.2f}, {vertex.z:.2f})")
# 访问组件
for component in model.components:
print(f"Component: {component.name}")
for instance in component.instances:
print(f" Instance at {instance.transform.origin}")
```
### 导出为 GLB
```
from openskp import SkpFile
model = SkpFile.open("my_model.skp")
# 将整个模型导出为 glTF Binary
model.export_glb("output.glb")
```
### 导出为 OBJ
```
from openskp import SkpFile
model = SkpFile.open("my_model.skp")
# 导出为带材质的 Wavefront OBJ
model.export_obj("output.obj")
```
### 提取图层和材质
```
from openskp import SkpFile
model = SkpFile.open("my_model.skp")
# 列出所有图层/标签
for layer in model.layers:
print(f"Layer: {layer.name} | Color: {layer.color} | Visible: {layer.visible}")
# 列出所有材质
for material in model.materials:
print(f"Material: {material.name}")
if material.texture:
material.texture.save(f"textures/{material.name}.png")
```
### 低级别二进制访问
```
from openskp.binary import VffReader
# 解析原始 TLV 流以进行自定义分析
reader = VffReader("my_model.skp")
for tag, length, data in reader.iter_tlv():
print(f"Tag: 0x{tag:04X} | Length: {length} bytes")
```
## 🏛️ 架构
OpenSKP 采用**三层架构**,将二进制解析与高级模型访问和导出分离开来:
```
graph TB
subgraph "Layer 3 — Export"
GLB["GLB Exporter"]
OBJ["OBJ Exporter"]
JSON["JSON Exporter"]
end
subgraph "Layer 2 — Structured Model"
SM["SkpFile API"]
GEO["GeometryVertices · Edges · Faces"] COMP["Components
Definitions · Instances"] MAT["Materials
Colors · Textures"] LAYER["Layers / Tags"] DC["Dynamic Components"] end subgraph "Layer 1 — Binary Parser" ZIP["ZIP Extractor"] TLV["TLV Parser"] HDR["Header Validator"] end subgraph "Input" SKP[".skp File"] end SKP --> HDR HDR --> ZIP ZIP --> TLV TLV --> SM SM --> GEO SM --> COMP SM --> MAT SM --> LAYER SM --> DC SM --> GLB SM --> OBJ SM --> JSON style SKP fill:#f59e0b,color:#000,stroke:#d97706 style SM fill:#3b82f6,color:#fff,stroke:#2563eb style TLV fill:#8b5cf6,color:#fff,stroke:#7c3aed style GLB fill:#10b981,color:#fff,stroke:#059669 style OBJ fill:#10b981,color:#fff,stroke:#059669 style JSON fill:#10b981,color:#fff,stroke:#059669 ``` ## 📁 项目结构 ``` openskp/ ├── README.md # You are here ├── LICENSE # MIT License ├── CONTRIBUTING.md # Contribution guide ├── CODE_OF_CONDUCT.md # Contributor Covenant v2.1 ├── CHANGELOG.md # Release history │ ├── python/ # 🐍 Python implementation │ ├── openskp/ │ │ ├── __init__.py │ │ ├── skp_file.py # High-level API (Layer 2) │ │ ├── binary/ # Binary parser (Layer 1) │ │ │ ├── vff_reader.py # VFF container reader │ │ │ ├── tlv_parser.py # Tag-Length-Value parser │ │ │ └── tags.py # Known tag definitions │ │ ├── model/ # Structured model objects │ │ │ ├── geometry.py # Vertex, Edge, Face │ │ │ ├── component.py # ComponentDef, Instance │ │ │ ├── material.py # Material, Texture │ │ │ └── layer.py # Layer / Tag │ │ └── export/ # Export engines (Layer 3) │ │ ├── glb.py │ │ ├── obj.py │ │ └── json.py │ ├── tests/ │ ├── setup.py │ └── pyproject.toml │ ├── typescript/ # 📘 TypeScript implementation (coming) ├── dart/ # 🎯 Dart implementation (planned) │ ├── docs/ # 📖 Documentation │ ├── BINARY_FORMAT.md # Reverse-engineered SKP format spec │ ├── ARCHITECTURE.md # Library architecture │ └── API_DESIGN.md # Cross-platform API contract │ ├── research/ # 🔬 Research notes │ └── METHODOLOGY.md # Reverse engineering methodology │ └── .github/ # GitHub configuration ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE/ ├── bug_report.md └── feature_request.md ``` ## 🔬 工作原理 SketchUp `.skp` 文件使用一种称为 **VFF** 的专有二进制格式(在 SketchUp 2021 中引入)。以下是 OpenSKP 读取它们的方式: ### 1. 文件头验证 每个 SKP 文件都以一个 magic marker (`FF FE FF 0E`) 开头,后跟一个 UTF-16LE 版本字符串。OpenSKP 会验证此文件头以确认格式兼容性。 ### 2. ZIP 提取 SKP 文件是一个 ZIP 存档(在文件头之后)。在其中,你会发现: - **`model.dat`** — 二进制几何体 payload(TLV 编码) - **`materials/*/material.xml`** — 材质定义和纹理 - **`meta/*.png`** — 缩略图和预览图像 ### 3. TLV 解析 `model.dat` 二进制文件使用 **Tag-Length-Value (TLV)** 编码: - **Tag**:2 字节标识符(little-endian) - **Length**:4 字节 payload 大小(little-endian) - **Value**:指定长度的原始字节 某些标签是*容器*——它们的 payload 是一系列嵌套的 TLV 元素,从而形成树状结构。 ### 4. 模型构建 OpenSKP 将已知的标签映射到几何图元、组件层级、图层和材质,以构建一个结构化且可查询的模型对象。 ### 5. 坐标转换 SketchUp 使用 **Z 轴向上、英寸** 坐标系统。当导出为 glTF(使用 Y 轴向上、米)时,OpenSKP 会应用: ``` x_mm = x_inches × 25.4 y_mm = z_inches × 25.4 z_mm = -y_inches × 25.4 ``` ## 📖 文档 | 文档 | 描述 | |:---------|:------------| | [二进制格式规范](docs/BINARY_FORMAT.md) | 逆向工程的 VFF / TLV 格式文档 | | [架构](docs/ARCHITECTURE.md) | 库设计、层级和模块结构 | | [API 设计](docs/API_DESIGN.md) | 带有示例的跨平台 API 契约 | | [研究方法](research/METHODOLOGY.md) | 我们是如何对该格式进行逆向工程的 | | [更新日志](CHANGELOG.md) | 版本历史和发布说明 | | [贡献](CONTRIBUTING.md) | 如何为 OpenSKP 做贡献 | ## 📄 许可证 OpenSKP 采用 [MIT 许可证](LICENSE) 发布。你可以自由地在商业和非商业项目中使用、修改和分发本软件。
标签:3D建模, Dart, Python, SketchUp, TypeScript, 云资产清单, 安全插件, 文件解析器, 无后门, 逆向工具, 逆向工程