# 从 0.1.0 使用方式升级到 0.2.0 树接口

本文说明 Commit 20—23 的增量，现已随 **0.2.0 正式发布**。已发布的 `BigSaltyMan/moonclip@0.1.0` 保持原样；安装该版本不会获得本文列出的五个新增库入口。0.2.0 的独立注册表消费者 native／JS 已通过，未覆盖注册表中的 0.1.0。正式发布状态见[0.2.0 说明](release-0.2.0.md)。

已发布版本的安装及验收见 [README](../README.md#从-mooncakes-使用)和[首版发布记录](release-0.1.0.md)。使用开发源码时，从仓库获取源码并使用[固定工具链](toolchain.md)，以当前[公开接口](../pkg.generated.mbti)为准。0.2.0 已完成真实注册表安装验证，精确安装命令见 README。

## 哪些内容是新增的

| 用途 | 0.1.0 已有 | 当前开发源码增量 |
| --- | --- | --- |
| Boolean 孔洞层级 | `boolean_tree` → `PolyTree64` | `boolean_tree_d` → `PolyTreeD` |
| 闭合偏移层级 | `offset_polygons` / `offset_polygons_d` 返回平铺轮廓 | `offset_tree` / `offset_tree_d` 返回整数／小数树 |
| 开放描边层级 | `stroke_polyline` / `stroke_polyline_d` 返回平铺区域 | `stroke_tree` / `stroke_tree_d` 返回整数／小数树 |
| 树类型与访问器 | `PolyTree64` / `PolyNode64` 及其访问器 | `PolyTreeD` / `PolyNodeD`；树提供 `roots()`、`to_paths()`，节点提供 `contour()`、`children()`、`depth()`、`is_hole()` |
| 演示与导出 | 平铺查看、NonZero SVG、v1 JSON | 六个整数／小数树入口的交互层级、边界选择高亮、保留结构的 v2 JSON |

新增库入口共 **5 个**。整数 `boolean_tree` 已在 0.1.0 中提供，是当前六入口消费者检查的一部分，不能计为新增。小数类型上的同名方法也不应重复算作六个全新的库函数。旧平铺入口的签名、默认值和返回类型不变。

## 按需要选择返回方式

1. 只需要最终区域边界，继续使用 `boolean_op(_d)`、`offset_polygons(_d)` 或 `stroke_polyline(_d)`。平铺结果保留完整轮廓和绕向，但数组没有显式父子关系。
2. 需要知道哪个孔洞属于哪个外轮廓，直接调用对应树入口。不要根据平铺数组顺序推断归属，也不要把两次独立公开调用当作同一份累计预算。
3. 已取得树但另一个处理环节只接受轮廓时，可调用 `to_paths()` 获取独立副本。转换会丢失显式父子关系；需要关系的部分应继续持有树。

完整受检调用保留在 [CLI 示例](../cmd/example/main.mbt)：`run_decimal_tree_example` 检查三层小数 Boolean，`run_offset_tree_example` 检查偏移，`run_stroke_tree_example` 检查普通路线及带孔描边。运行 `moon run --target native cmd/example`；不需要另复制一份未受检的算法示例。

## 树的语义与所有权

- 树描述本次运算**完成后的最终填充区域**。偏移可能合并、分裂或消灭孔洞；描边路线本身没有可直接沿用的孔洞树。
- 根外轮廓深度为 1，孔洞为 2，孔中岛为 3，后续交替。通过 `roots()` 和 `children()` 遍历关系，用 `depth()`、`is_hole()` 读取节点属性。
- 不保证轮廓的同级顺序或环起点稳定。按当前树的父子关系使用数据，不依赖上一轮调用的编号或数组位置。
- 树独立拥有数据，根数组、孩子数组、节点轮廓与 `to_paths()` 返回副本；修改这些副本不会修改树。数组副本和节点索引本身不是跨调用身份标识。
- 成功空树表示最终区域为空；错误仍是 `Err(ClipError)`，不能用空树替代，也不发布部分结果。

## 小数精度、完整宽度与预算

小数树先按 Precision 量化到整数网格，沿用整数区域已构建的父子关系，再解码坐标。Precision 默认 3，支持 0—6；变化可能影响可表达的区域与层级。输出 Double 并不表示任意精度的浮点拓扑。严格量化合并、坐标和退化错误继续生效，详见[小数契约](decimal.md)。

偏移树沿用平铺偏移的有符号单侧 delta、默认 NonZero 和四种连接。描边树仍只接受**一条开放路线**，width 表示完整宽度，两侧各半；默认 Butt，支持 Square / Round 端点和四种连接。末点返回起点仍解释开放端点，不能自动切换为闭合偏移。整数次网格宽度、空路线和单点的快捷空结果仍先验证输入并计费。完整边界见[支持范围](scope.md)和[组合契约](composition.md)。

同一次树调用的输入准备、量化、生成、清理、树构建及小数解码共享累计预算，新增树存储和解码也计费，释放临时存储不退款。**同一输入的平铺调用成功，不保证树调用有足够预算成功**。树构建使用 PolyTree 阶段，小数输出使用 DecimalOutput；其他错误保留真实阶段。访问器另行复制和演示序列化属于调用之外的成本。

## 演示的 v2 JSON 与核心 API 分开使用

开发演示默认仍为平铺。切换 tree 后，Boolean、Offset、Stroke 分别选择整数或小数树入口；Minkowski 只允许整数平铺。层级面板可展开孩子并选择对应轮廓，选择只描边，主结果仍按 NonZero 复合路径保留孔洞。

平铺 JSON 保持 `MoonClipDemo` v1；树导出使用 v2，`result.paths[i]` 与 `result.tree.nodes[i]` 一一对应，包含根、父子索引、深度和孔洞标记。导出中的 `request.version` 仍为 1，可重放桥接请求；SVG 仍只输出结果区域，不输出输入或选择高亮。编辑、错误或切换模式会清除旧树和选择，迟到响应不能恢复旧导出。

JSON 版本是演示协议，和库版本号不是同一个概念。详情见[演示协议](demo.md#unreleased-孔洞层级查看与桥接协议)，实际浏览器记录沿用[Commit 23 验收](demo-acceptance.md#commit23)。

## 升级检查与证据范围

候选包从真实归档解压后，在仓库外对 native、JS 分别运行六个树入口。每个入口的断言成功后才输出 `TREE_API_OK` 标记；两个目标必须分别收齐六项，不可相互替代。说明及历史 CI 见[增量验收](acceptance-trees.md)，候选生成方法见[发布检查清单](release-checklist.md#后续树能力版本发布前检查)。

新增定向测试和消费者检查没有增加上游参考矩阵。现有 1384 个案例、2276 项能力检查没有逐项覆盖全部新树入口；当前库回归为两目标各 2323 项，演示桥接另计 20 项。新增树入口没有单独性能测量，不从首版平铺基准推导树构建的耗时或内存。
