npm package: @manycore/geom-data-exchange
Description: ## 包含功能： - 定义了点，向量，矩阵，坐标系，各类曲线，曲面，裁剪曲线曲面等常用几何元素的对外暴露数据格式（数据交换接口）。 - 定义了顶点，边，面片，环，翼边，体，组件，组件实例等常用的拓扑元素的对外暴露数据格式（数据交换接口）。 - 定义了以上数据格式的序列化和反序列化标准接口。 - 提供了以上数据交换接口的实现（基本数据+序列化+反序列化，不包含任何几何造型算法）。
Latest version: 1.0.0-rc.3

# @manycore/geom-data-exchange （几何数据交换包）

## 包含功能：
- 定义了点，向量，矩阵，坐标系，各类曲线，曲面，裁剪曲线曲面等常用几何元素的对外暴露数据格式（数据交换接口）。
- 定义了顶点，边，面片，环，翼边，体，组件，组件实例等常用的拓扑元素的对外暴露数据格式（数据交换接口）。
- 定义了以上数据格式的序列化和反序列化标准接口。
- 提供了以上数据交换接口的实现（基本数据+序列化+反序列化，不包含任何几何造型算法）。

## 其他说明：
- 几何元素部分保持了和内部算法包@qunhe/math一致的序列化格式定义，两者的json文本是通用的。
- 拓扑元素部分的json定义和内部@qunhe/brep算法包是不通用的，原因主要是两点：
    - 公司内部的造型系统还没有完全统一，并没有全部使用BRep造型。
    - 为了降低第三方公司开发人员的理解成本，默认省去了Loop（环），Fin（翼边），只保留了Vertex（顶点），Edge（边），Face（面）。
- 和目前公司内部的实现机制一样，当传递那些孤立的没有类型标记的数据时，双方必须知道上下文。
    - 例如Point2d，Vector2d、Matrix类型都不是SubType类型，没有类型标记，如果这类传递对象是孤立的，
      没有被另外一个SubType对象包含，那么当把它们序列化后，json信息中并不包含类型说明。
    - 这种情况下数据交换的双方必须知道具体的数据定义规则，例如第一个是什么类型，第二个是什么类型。
- 公司内部的第二方可以依据本包的基础实现进行扩展，定义其他格式进行暴露。
<br>
<br>
<h1 id ="doc"> 详细文档 </h1>
<details>
<summary> 详细文档 </summary>

# 数据交换模块帮助文档

## 类型列表
```ts
IObject,
    //#region  IObject
    IVector2d,
    IVector3d,
    IPoint2d,
    IPoint3d,
    ICCS2d,
    ICCS3d,
    IMatrix,
    IUV,
    IInterval,
    ICompositeCurve2d,
    ICurveLoop2d,
    IGeomRegion2d,
    ISubType,
        //#region  ISubType
        IGeometry,
            //#region  IGeometry
            ICurve2d,
                //#region  ICurve2d
                ILine2d,
                IPolyline2d,
                IRay2d,
                ICircle2d,
                IEllipse2d,
                IBezierCurve2d,
                INurbsCurve2d,
                ITrimmedCurve2d,
                    ILineSegment2d,
                    IArc2d,
                    IEllipticArc2d,
                //#endregion ICurve2d
            ICurve3d,
                //#region  ICurve2d
                ILine3d,
                IPolyline3d,
                IRay3d,
                ICircle3d,
                IEllipse3d,
                IBezierCurve3d,
                INurbsCurve3d,
                ICurveOnSurface,
                ICurveOnSurfaces,
                ITrimmedCurve3d,
                    ILineSegment3d,
                    IArc3d,
                    IEllipticArc3d,
                //#endregion ICurve2d
            ISurface,
                //#region  ISurface
                ISurfaceWithFrame,
                    //#region  ISurfaceWithFrame
                    IPlane,
                    ICylinder,
                    ICone,
                    ITorus,
                    //#endregion ISurfaceWithFrame
                INurbsSurface,
                IGenericCylinder,
                IRevolvedSurface,
                ITrimmedSurface,
                IRectTrimmedSurface,
                //#endregion  ISurface
            //#endregion  IGeometry
        IName,
            //#region  IName
            NameTypes,
            ITextName,
            IStructuredName,
            //#endregion  IName
        ITopology,
            //#region  ITopology
            IDesign2dVertex,
            IDesign2dEdge,
            IDesign2dRegion,
            IVertex,
            IEdge,
            IFace,
            IFin,
            ILoop,
            IOutline,
            IBodyBase,
                //#region  Body
                ModelTypes,
                IGeometric2dDesign,
                IBody,
                IMeshBody,
                //#endregion  Body
            IComponent,
            IInstance
            //#endregion  ITopology
    //#endregion  ISubType
//#endregion  IObject
```
<br>

## 接口 `IObject`
所有对外数据的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| 无 | | |
<br>

## 接口 `ISubType` 继承 `IObject`
所有具有类型标识的对外数据的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `subType` | `string` | 具体实现类的类型标识；详细的类型列表请查看DefaultSubTypes。<ol><li>外部使用者一般不需要关心。</ol> |
<br>

## 接口 `IGeometry` 继承 `ISubType`
所有几何数据的基类。
<ol>
<li>注意，所有几何数据都是SubType。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| 无 | | |
<br>

## 接口 `IVector2d` 继承 `IObject`
二维向量。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `x` | `number` | 二维向量的x坐标。 |
| `y` | `number` | 二维向量的y坐标。 |
<br>

## 接口 `IVector3d` 继承 `IObject`
三维向量。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `x` | `number` | 三维向量的x坐标。 |
| `y` | `number` | 三维向量的y坐标。 |
| `z` | `number` | 三维向量的z坐标。 |
<br>

## 接口 `ICCS2d` 继承 `IObject`
二维局部坐标系。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint2d` | 坐标系原点。 |
| `dx` | `IVector2d` | 坐标系x轴方向。 |
| `dy` | `IVector2d` | 坐标系y轴方向。 |
<br>

## 接口 `ICCS3d` 继承 `IObject`
三维局部坐标系。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 坐标系原点。 |
| `dx` | `IVector3d` | 坐标系x轴方向。 |
| `dy` | `IVector3d` | 坐标系y轴方向。 |
| `dz` | `IVector3d` | 坐标系z轴方向。 |
<br>

## 接口 `IMatrix` 继承 `IObject`
变换矩阵。
<ol>
<li>不区分3x3、4x4，按数组长度来判断；
<li>矩阵元素按列向量方式排成一维数组。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `elements` | `readonly number[]` | 矩阵元素按列向量方式排成一维数组。 |
<br>

## 接口 `IUV` 继承 `IObject`
二维参数域内的UV点。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `u` | `number` | 二维参数域的第一个参数u。 |
| `v` | `number` | 二维参数域的第二个参数v。 |
<br>

## 接口 `IInterval` 继承 `IObject`
参数区间。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `start` | `number` | 参数区间的起点。 |
| `end` | `number` | 参数区间的终点。 |
<br>

## 接口 `ICurve2d` 继承 `IGeometry`
二维曲线的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| 无 | | |
<br>

## 接口 `ICurve3d` 继承 `IGeometry`
三维曲线的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| 无 | | |
<br>

## 接口 `ITrimmedCurve2d` 继承 `ICurve2d`
二维裁剪曲线（有界曲线）。
<ol>
<li>注意：截止目前，除了圆弧（Arc）和椭圆弧（EllipticArc）之外，其他2D裁剪曲线的方向永远和原始曲线保持一致。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curve` | `ICurve2d` | 未裁剪的原始曲线。 |
| `startParam` | `number` | 获取和设置裁剪曲线的起点参数。 |
| `endParam` | `number` | 获取和设置裁剪曲线的终点参数。 |
<br>

## 接口 `ITrimmedCurve3d` 继承 `ICurve3d`
三维裁剪曲线（有界曲线）。
<ol>
<li>注意：截止目前，所有3D裁剪曲线的方向永远和原始曲线保持一致。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curve` | `ICurve3d` | 未裁剪的原始曲线。 |
| `startParam` | `number` | 起点的参数。 |
| `endParam` | `number` | 终点的参数。 |
<br>

## 接口 `ICircle2d` 继承 `ICurve2d`
二维圆。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint2d` | 圆的圆心。 |
| `radius` | `number` | 圆的半径。 |
<br>

## 接口 `ICircle3d` 继承 `ICurve3d`
三维圆。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 圆的圆心。 |
| `radius` | `number` | 圆的半径。 |
| `ccs` | `ICCS3d` | 三维圆的局部坐标系（圆心，参数域x轴，参数域y轴，法向） |
<br>

## 接口 `ILine2d` 继承 `ICurve2d`
二维直线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint2d` | 二维直线的参数原点。 |
| `direction` | `IVector2d` | 二维直线的方向（单位向量）。 |
<br>

## 接口 `ILine3d` 继承 `ICurve3d`
三维直线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 三维直线的参数原点。 |
| `direction` | `IVector3d` | 三维直线的方向（单位向量）。 |
<br>

## 接口 `IRay2d` 继承 `ICurve2d`
二维射线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint2d` | 二维射线的原点。 |
| `direction` | `IVector2d` | 二维射线的方向（单位向量）。 |
<br>

## 接口 `IRay3d` 继承 `ICurve3d`
三维射线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 三维射线的原点。 |
| `direction` | `IVector3d` | 三维射线的方向（单位向量）。 |
<br>

## 接口 `IEllipse2d` 继承 `ICurve2d`
二维椭圆

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint2d` | 椭圆的圆心。 |
| `majorRadius` | `number` | 椭圆长轴半径，也就是x轴方向的半径。 |
| `minorRadius` | `number` | 椭圆短轴半径，也就是y轴方向的半径。 |
| `ccs` | `ICCS2d` | 二维椭圆的局部坐标系（圆心，参数域x轴，参数域y轴） |
<br>

## 接口 `IEllipse3d` 继承 `ICurve3d`
三维椭圆

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 椭圆的圆心。 |
| `majorRadius` | `number` | 椭圆长轴半径，也就是x轴方向的半径。 |
| `minorRadius` | `number` | 椭圆短轴半径，也就是y轴方向的半径。 |
| `ccs` | `ICCS3d` | 三维椭圆的局部坐标系（圆心，参数域x轴，参数域y轴，法向） |
<br>

## 接口 `ILineSegment2d` 继承 `ITrimmedCurve2d`
二维直线段

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `line` | `ILine2d` | 获取或者设置直线段所在的直线。 |
| `startParam` | `number` | 获取或者设置直线段的起点参数。 |
| `endParam` | `number` | 获取或者设置直线段的终点参数。 |
| `startPoint` | `IPoint2d` | 计算直线段的起点。 |
| `endPoint` | `IPoint2d` | 计算直线段的终点。 |
<br>

## 接口 `ILineSegment3d` 继承 `ITrimmedCurve3d`
三维直线段

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `line` | `ILine3d` | 获取或者设置直线段所在的直线。 |
| `startParam` | `number` | 获取或者设置直线段的起点参数。 |
| `endParam` | `number` | 获取或者设置直线段的终点参数。 |
| `startPoint` | `IPoint3d` | 计算直线段的起点。 |
| `endPoint` | `IPoint3d` | 计算直线段的终点。 |
<br>

## 接口 `IArc2d` 继承 `ITrimmedCurve2d`
二维圆弧

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `circle` | `ICircle2d` | 二维圆弧所在的圆。 |
| `startParam` | `number` | 二维圆弧的参数起点（弧度值）。 |
| `endParam` | `number` | 二维圆弧的参数终点（弧度值）。 |
| `clockSign` | `number` | 圆弧的转向：1 = 逆时针，-1 = 顺时针。 |
| `origin` | `IPoint2d` | 圆弧的圆心。 |
| `radius` | `number` | 圆弧的半径。 |
<br>

## 接口 `IArc3d` 继承 `ITrimmedCurve3d`
三维圆弧

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `circle` | `ICircle3d` | 三维圆弧所在的圆。 |
| `startParam` | `number` | 三维圆弧的参数起点（弧度值）。 |
| `endParam` | `number` | 三维圆弧的参数终点（弧度值）。 |
| `origin` | `IPoint3d` | 圆的圆心。 |
| `radius` | `number` | 圆的半径。 |
<br>

## 接口 `IEllipticArc2d` 继承 `ITrimmedCurve2d`
二维椭圆弧

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `ellipse` | `IEllipse2d` | 椭圆弧所在的椭圆。 |
| `startParam` | `number` | 椭圆弧的参数起点（弧度值）。 |
| `endParam` | `number` | 椭圆弧的参数终点（弧度值）。 |
| `ccs` | `ICCS2d` | 二维椭圆弧所在的椭圆的局部坐标系。 |
| `majorRadius` | `number` | 椭圆长轴半径。 |
| `minorRadius` | `number` | 椭圆短轴半径。 |
| `clockSign` | `number` | 1 = 逆时针，-1 = 顺时针。 |
<br>

## 接口 `IEllipticArc3d` 继承 `ITrimmedCurve3d`
三维椭圆弧

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `ellipse` | `IEllipse3d` | 椭圆弧所在的椭圆。 |
| `startParam` | `number` | 椭圆弧的参数起点（弧度值）。 |
| `endParam` | `number` | 椭圆弧的参数终点（弧度值）。 |
| `ccs` | `ICCS3d` | 三维椭圆弧所在的椭圆的局部坐标系。 |
| `majorRadius` | `number` | 椭圆长轴半径。 |
| `minorRadius` | `number` | 椭圆短轴半径。 |
<br>

## 接口 `IBezierCurve2d` 继承 `ICurve2d`
二维贝塞尔曲线

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `controlPoints` | `IPoint2d[]` | 贝塞尔曲线的控制顶点 |
| `interval` | `IInterval` | 贝塞尔曲线的参数区间 |
<br>

## 接口 `IBezierCurve3d` 继承 `ICurve3d`
三维贝塞尔曲线

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `controlPoints` | `IPoint3d[]` | 贝塞尔曲线的控制顶点 |
| `interval` | `IInterval` | 贝塞尔曲线的参数区间 |
<br>

## 接口 `INurbsCurve2d` 继承 `ICurve2d`
二维的非均匀有理B样条曲线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `degree` | `number` | nurbs曲线的次数。 |
| `knots` | `number[]` | nurbs曲线的节点向量。 |
| `controlPoints` | `IPoint2d[]` | nurbs曲线的控制顶点。 |
| `weights` | `number[]` | nurbs曲线控制顶点的权重。 |
<br>

## 接口 `INurbsCurve3d` 继承 `ICurve3d`
三维的非均匀有理B样条曲线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `degree` | `number` | nurbs曲线的次数。 |
| `knots` | `number[]` | nurbs曲线的节点向量。 |
| `controlPoints` | `IPoint3d[]` | nurbs曲线的控制顶点。 |
| `weights` | `number[]` | nurbs曲线控制顶点的权重。 |
<br>

## 接口 `IPolyline2d` 继承 `ICurve2d`
二维折线段

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `points` | `IPoint2d[]` | 构成折线段的有序点列。 |
| `tangents` | `IVector2d[]` | 折线段每点处的切向量。 |
<br>

## 接口 `IPolyline3d` 继承 `ICurve3d`
三维折线段

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `points` | `IPoint3d[]` | 构成折线段的有序点列。 |
| `tangents` | `IVector3d[]` | 折线段每点处的切向量。 |
<br>

## 接口 `ICompositeCurve2d` 继承 `IObject`
二维组合曲线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curves` | `ICurve2d[]` | 前后首尾相接的有界曲线列表 |
<br>

## 接口 `ICompositeCurve3d` 继承 `IObject`
三维组合曲线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curves` | `ICurve3d[]` | 前后首尾相接的有界曲线列表 |
<br>

## 接口 `ICurveLoop2d` 继承 `IObject`
二维曲线环。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curves` | `ICurve2d[]` | 前后首尾相接成环的有界曲线列表。 |
<br>

## 接口 `IGeomRegion2d` 继承 `IObject`
不带拓扑信息的纯几何二维区域。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `outerLoop` | `ICurveLoop2d` | 二维区域的外轮廓。 |
| `innerLoops` | `ICurveLoop2d[]` | 二维区域内部的空洞。 |
<br>

## 接口 `ISurface` 继承 `IGeometry`
所有曲面的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| 无 | | |
<br>

## 接口 `ISurfaceWithFrame` 继承 `ISurface`
带局部标架的曲面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `ccs` | `ICCS3d` | 3维曲面的局部标架（表达定位和朝向）。 |
<br>

## 接口 `IPlane` 继承 `ISurfaceWithFrame`
平面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 平面的原点。 |
| `normal` | `IVector3d` | 平面的法向量。 |
| `ccs` | `ICCS3d` | 平面的定位标架。<ol><li>z轴为平面的法向量；<li>x轴和y轴分别为平面坐标系的x轴和y轴。</ol> |
<br>

## 接口 `ICylinder` 继承 `ISurfaceWithFrame`
圆柱面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 圆柱中心轴的原点。 |
| `direction` | `IVector3d` | 圆柱中心轴的方向。 |
| `radius` | `number` | 圆柱面半径 |
| `ccs` | `ICCS3d` | 圆柱面的定位标架。<ol><li>z轴为圆柱的中心轴；z轴正向为参数v正向；<li>x轴朝y轴转动的方向为参数u正向；<li>x轴和圆柱交点对应参数域原点。</ol> |
<br>

## 接口 `ICone` 继承 `ISurfaceWithFrame`
圆锥面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 圆锥中心轴的原点。<ol><li>注意：不一定是圆锥的顶点。</ol> |
| `direction` | `IVector3d` | 圆锥中心轴的方向；也就是局部标架的z轴方向。 |
| `radius` | `number` | 定位标架的xy平面和圆锥相交得到的圆的半径。 |
| `semiAngle` | `number` | 圆锥面的半角（弧度值）。也就是圆锥面和它的轴所成的角度。 |
| `ccs` | `ICCS3d` | 圆锥的定位标架。<ol><li>z轴为圆锥的中心轴；<li>x轴和圆锥面交点对应参数域原点。<li>x轴朝y轴转动方向为参数u正向；<li>z轴正向为参数v正向；</ol> |
<br>

## 接口 `ITorus` 继承 `ISurfaceWithFrame`
圆环面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `origin` | `IPoint3d` | 圆环中心轴的原点；也是圆环的中心点。 |
| `direction` | `IVector3d` | 圆环中心轴的方向。 |
| `majorRadius` | `number` | 圆环面的大圆半径。 |
| `minorRadius` | `number` | 圆环面的小圆半径。 |
| `ccs` | `ICCS3d` | 圆环的定位标架。<ol><li>原点o为圆环中心；<li>z轴为圆环的中心轴；<li>x轴y轴定义在圆环的大圆所在的平面内；<li>x轴和圆环面的交点对应参数域原点；<li>按z轴和右手法则定义u参数方向，再按u参数方向和右手法则定义小圆上的v参数方向；</ol> |
<br>

## 接口 `IGenericCylinder` 继承 `ISurfaceWithFrame`
广义柱面（拉伸面）。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `baseCurve` | `ICurve2d` | 在局部坐标系的xy平面上定义的拉伸面轮廓线。 |
| `height` | `number` | 沿局部坐标系的z轴方向的拉伸高度。 |
| `ccs` | `ICCS3d` | 广义柱面的定位标架（xy平面上定义轮廓线，z轴方向为拉伸方向）。 |
<br>

## 接口 `IRevolvedSurface` 继承 `ISurface`
旋转面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `baseCurve` | `ITrimmedCurve3d` | 旋转面的轮廓曲线。 |
| `axis` | `ILine3d` | 旋转面的旋转轴。 |
| `startAngle` | `number` | 旋转面的起始旋转角度（弧度值）。 |
| `endAngle` | `number` | 旋转面的终止旋转角度（弧度值）。 |
<br>

## 接口 `INurbsSurface` 继承 `ISurface`
非均匀有理B样条曲面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `udegree` | `number` | nurbs曲面的u向次数。 |
| `vdegree` | `number` | nurbs曲面的v向次数。 |
| `uknots` | `number[]` | nurbs曲面的u向节点向量。 |
| `vknots` | `number[]` | nurbs曲面的v向节点向量。 |
| `controlPoints` | `IPoint3d[][]` | nurbs曲面的控制网格。<ol><li>如果以u向为行，v向为列，那么控制顶点是按列向排列的</ol>第一列   第二列    第三列   第四列CP[0]，  CP[1]，  CP[2]，  CP[3]（0,0）-------- U --------&gt;（1,0）  |                         |  |                         |  V                         V  |                         |  |                         |  v                         v（0,1）-------- U --------&gt;（1,1） |
| `weights` | `number[][]` | nurbs曲面的控制网格每个顶点的权重。 |
<br>

## 接口 `ITrimmedSurface` 继承 `ISurface`
裁剪曲面（有界曲面）。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `surface` | `ISurface` | 未裁剪的完整曲面。 |
| `sense` | `boolean` | 裁剪曲面和曲面朝向是否一致。 |
| `outerLoop` | `ICurve3d[]` | 裁剪曲面的外边界。 |
| `innerLoops` | `ICurve3d[][]` | 裁剪曲面的内边界（洞）。 |
| `uvOuterLoop` | `ICurve2d[]` | 裁剪曲面的外边界在曲面参数域上对应的参数域曲线。 |
| `uvInnerLoops` | `ICurve2d[][]` | 裁剪曲面的内边界在曲面参数域上对应的参数域曲线。 |
<br>

## 接口 `IRectTrimmedSurface` 继承 `ISurface`
对应到参数域上为矩形的裁剪曲面。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `surface` | `ISurface` | 未裁剪的完整曲面。 |
| `sense` | `boolean` | 裁剪曲面和曲面朝向是否一致。 |
| `uvMin` | `IUV` | 矩形参数域的左下角。 |
| `uvMax` | `IUV` | 矩形参数域的右上角。 |
<br>

## 接口 `ICurveOnSurface` 继承 `ICurve3d`
通过曲面参数域上的二维曲线定义的三维曲线或曲线段。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `pCurve` | `ICurve2d` | 曲面参数域上定义的二维曲线（可能是裁剪曲线）。 |
| `surface` | `ISurface` | 背景曲面。 |
<br>

## 接口 `ICurveOnSurfaces` 继承 `ICurve3d`
一条（贴近一簇曲面片的）三维曲线。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curve3d` | `ICurve3d` | 贴近一簇曲面片的三维曲线。 |
| `pCurves` | `ICurveOnSurface[]` | 三维曲线投影在每个曲面上的形成的参数域二维曲线。 |
<br>

## 接口 `IGeometric2dDesign` 继承 `IBodyBase`
一个二维平面设计模型。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `faces` | `IDesign2dRegion[]` | 2D设计的区域 |
| `edges` | `IDesign2dEdge[]` | 模型的所有边。 |
| `vertices` | `IDesign2dVertex[]` | 模型的所有顶点。 |
<br>

## 接口 `IDesign2dRegion` 继承 `ITopology`
二维平面设计模型的一个区域（面片）。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `edgeLoops` | `IDesign2dEdge[][]` | 面片的边界。<ol><li>边界是由一系列首尾相接的边构成，它们形成若干个封闭的环；<li>第一个数组表示面片的外边界环，其他表示内边界环（洞）；<li>每条边都是用下标表示，也就是父对象IGeometric2dDesign内的edges数组的下标。</ol> |
| `edgeSenses` | `boolean[][]` | 边界环本身的转向和其中每条边的方向是否一致。<ol><li>例如一个四边形平面片的边界转向可以是逆时针的，但是它的最左侧边的方向可以是从下往上的，和四边形边界的转向相反。<li>true表示对应序号的边和边界转向一致，false表示不一致。</ol> |
<br>

## 接口 `IDesign2dEdge` 继承 `ITopology`
二维平面设计模型的边。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curve` | `ICurve2d` | 边所依赖的曲线。 |
| `sense` | `boolean` | 边的方向（从起点到终点）是否和所依赖的曲线的方向一致。<ol><li>例如一条直线方向是和X轴正向一样的，但是以这条直线为几何元素的一条边可以是沿X轴负反向的。<li>true表示两者方向一致，false表示不一致。</ol> |
| `vertices` | `IDesign2dVertex[]` | 边的两个顶点。 |
<br>

## 接口 `IDesign2dVertex` 继承 `ITopology`
二维平面设计模型的顶点。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `point` | `IPoint2d` | 顶点的坐标位置 |
<br>

## 接口 `ITopology` 继承 `ISubType`
所有拓扑对象的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `name` | `IName` | 拓扑对象的持久命名。<ol><li>命名可以为空，表示这个对象没有名字；<li>名字的唯一性需要考虑对应的上下文，可能是在某一领域内唯一；<li>名字种类分为文本型名字和结构化名字两种，具体请参考派生类的说明；<li>对象是否有持久命名，以及名字的具体构成方式由内部造型引擎和具体需求决定，和拓扑对象的类型没有必然联系。<ol><li>比如硬装的墙面和定制衣柜的某个面都是Face类型，但可能一个有命名一个没有命名。</ol></ol> |
| `properties` | `IDynamicObject` | 挂载在该对象上的非标数据，业务方自定义设置、解析和使用。 |
| `innerId` | `string` | 该对象在内部系统中的ID。<ol><li>目前只有BRep类型的数据才有这个Id：<ol><li>Body的Id是系统生成的uuid；<li>Face的Id是它在Body的所有Face中的历史序号（index）；<li>Edge的Id是它在Body的所有Edge中的历史序号（index）；<li>Vertex的Id是它在Body的所有Vertex中的历史序号（index）；</ol></ol> |
<br>

## 接口 `IName` 继承 `ISubType`
名字的基类。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `nameType` | `NameTypes` | 名字表示方式：Text 或者 Struct |
<br>

## 接口 `ITextName` 继承 `IName`
文本式名字。
<ol>
<li>最底层对象名字直接由文本构成，或者已经通过结构化名字转换成了string型名字；或者业务方有自己的黑盒命名体系。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `name` | `string` | 获取对象的名字。 |
<br>

## 接口 `IStructuredName` 继承 `IName`
结构化名字。
<ol>
<li>结构化名字由对象的类型、生成源的名字、关联对象的名字（可选）、额外编号（可选）4部分组成的。
<li>注意：结构化名字不能有循环依赖，例如父母的名字不能又由后代决定。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `entityType` | `string` | 被命名对象的类型，例如V，E，F分别代表顶点，边，面。 |
| `progenitors` | `IName[]` | 当前对象的生成源。例如：<ol><li>两个Face相互裁剪后生成的公共边，它的生成源可以定义为这两个Face。<li>拉伸一个平面轮廓成为一个实体，那么侧面某个Face的生成源可以定义为轮廓上的一条边。</ol> |
| `accessories` | `IName[]` | 当生成源无法区分子对象时，可以增加辅助关联对象来区分。<ol><li>例如平面板件开槽，在布尔结果中的顶面被切割成了3块；那么可以利用未变化的相邻边或者其他附属对象来区分这3个新面。</ol> |
| `postfix` | `string | undefined` | 对象的额外编号或者额外类型信息。例如：<ol><li>平面板件的顶面和底面的区分，顶底面上的顶点的区分；<li>某些极端情况下我们会用index做后缀来区分新对象。</ol> |
<br>

## 接口 `IBodyBase` 继承 `ITopology`
所有几何体（模型）的基类。
<ol>
<li>注意：子对象不能跨Body（模型）被多个Body（模型）共享；例如一条边或者一个面不能同时属于两个体。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `modeltype` | `ModelTypes` | 模型分类（2D平面设计，实体造型模型，或者三角网格模型）。 |
| `vertices` | `any[]` | 模型子对象 - 顶点。 |
| `faces` | `any[]` | 模型子对象 - 面。 |
| `edges` | `any[]` | 模型子对象 - 边。 |
<br>

## 接口 `IBody` 继承 `IBodyBase`
3D几何造型体（solid body, sheet body, wire body）。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `faces` | `IFace[]` | 造型体的所有面片。 |
| `edges` | `IEdge[]` | 造型体的所有边。 |
| `vertices` | `IVertex[]` | 造型体的所顶点。 |
<br>

## 接口 `IFace` 继承 `ITopology`
几何模型的面片（三维）。
<ol>
<li>注意：为了数据的简洁性，我们只导出了正向的数据关系；Face到Body的反向关系可以通过正向关系间接获取到。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `surface` | `ISurface` | 三维面片所依赖的曲面。<ol><li>例如一个四边形平面片所依赖的平面，或者一个三角形球面片所依赖的球面。</ol> |
| `sense` | `boolean` | 面片的朝向是否和它所依赖的曲面的朝向一致。<ol><li>例如一个被裁剪成四边形的圆柱面片的朝向，可以被定义为指向中心轴线的方向；</ol>  而圆柱曲面本身的朝向可以被定义为从圆柱轴线指向圆柱面的方向。<ol><li>true表示面片和曲面两者朝向一致，false表示不一致。</ol> |
| `edgeLoops` | `IEdge[][]` | 面片的边界。<ol><li>边界由一系列首尾相接的边构成的环组成；<li>数组当中的第一个环是面片的外边界环，其余表示的是内边界环（洞）；可以没有内边界；<li>边界环的每条边都是用下标表示，也就是父对象Body的edges数组的下标。</ol> |
| `edgeSenses` | `boolean[][]` | 边界环本身的转向和其中每条边的方向是否一致。<ol><li>例如一个四边形平面片的边界转向可以是逆时针的；但它最左侧的边的方向可以是从下往上的，和四边形边界的转向相反。<li>true表示对应序号的边和边界转向一致，false表示不一致。</ol> |
| `uvEdgeLoops` | `ICurve2d[][]` | 边界环的每条边，在曲面的2维参数域空间当中对应的参数曲线。<ol><li>在很多系统中也被叫做pcurve；<li>注意：这不是一个必须的属性；如果内部已经计算过，则会导出来提供给外部客户直接使用。</ol> |
| `loops` | `ILoop[]` | 面片的Brep外环和内环。<ol><li>只有当内部模型为Brep模型，并且做对外数据交换时明确要求输出Brep环结构和翼边结构时才会存在。<li>数组中第一个为外环，其余为内环。</ol> |
<br>

## 接口 `IEdge` 继承 `ITopology`
几何模型的边（三维）。
<ol>
<li>注意：为了数据的简洁性，我们只导出了正向的数据关系；Edge到Body/Face的反向关系可以通过正向关系间接获取到。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `curve` | `ICurve3d` | 边所依赖的曲线。 |
| `sense` | `boolean` | 边的方向（从起点到终点）是否和所依赖的曲线的方向一致。<ol><li>例如一条直线的方向是和X轴正向一致的，但是以这条直线为几何元素的一条边可以是沿X轴负方向的。<li>true表示两者方向一致，false表示不一致。</ol> |
| `vertices` | `IVertex[]` | 边的顶点。 |
<br>

## 接口 `IVertex` 继承 `ITopology`
几何模型的顶点（三维）。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `point` | `IPoint3d` | 顶点的坐标位置 |
<br>

## 接口 `IOutline` 继承 `ITopology`
网格模型上额外标记出来的线条或线路。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `vertices` | `number[]` | 边的两个顶点的下标。 |
<br>

## 接口 `IFin` 继承 `ITopology`
几何模型的翼边（三维）。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `edge` | `IEdge` | 翼边所引用的边。 |
| `sense` | `boolean` | 翼边的方向是否和所引用的边的方向一致。<ol><li>例如一个四边形的面片，我们沿它的法向的反方向观察这个面片时，它的外环的左侧翼边的方向是从上到下，</ol>  但这条翼边所依赖的实际边的方向可能是从下到上的。<ol><li>true表示两者方向一致，false表示不一致。</ol> |
<br>

## 接口 `ILoop` 继承 `ITopology`
几何模型的Brep环（三维）。
<ol>
<li>注意：为了数据的简洁性，我们只导出了正向的数据关系；Loop到Face的反向关系可以通过正向关系间接获取到。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `fins` | `IFin[]` | 构成环的翼边。 |
<br>

## 接口 `IMeshBody` 继承 `IBodyBase`
3D的三角网格

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `vertices` | `number[]` | 三角网格所有顶点的坐标组成的数组。<ol><li>vertices[3 * i]为第 i 个顶点的 x 坐标；<li>vertices[3 * i + 1]为第 i 个顶点的 y 坐标；<li>vertices[3 * i + 2]为第 i 个顶点的 z 坐标；</ol> |
| `faces` | `number[]` | 每个三角面片的三个顶点的下标构成的数组。<ol><li>faces[3 * j]为第 j 个三角面片的第一个顶点的下标；它对应的顶点坐标是：<ol><li>vertices[3 * faces[3 * j]]<li>vertices[3 * faces[3 * j] + 1]<li>vertices[3 * faces[3 * j] + 2]；</ol><li>faces[3 * j + 1]为第 j 个三角面片的第二个顶点的下标；<li>faces[3 * j + 2]为第 j 个三角面片的第三个顶点的下标。</ol> |
| `outline` | `IOutline[]` | 额外标记的线条或者路径。 |
<br>

## 接口 `IComponent` 继承 `ITopology`
一个组件。

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `bodies` | `IBodyBase[]` | 组件包含的体。<ol><li>一个组件可以包含0..n个体（Body，MeshBody，或者2D平面设计）；<li>但一个体只能被一个组件所有。</ol> |
| `subInstances` | `IInstance[]` | 组件包含的实例。<ol><li>一个组件可以包含0..m个实例；<li>注意，组件必须通过实例来引用其他组件，组件不能直接引用组件。</ol> |
<br>

## 接口 `IInstance` 继承 `ITopology`
组件的实例（用于解决模型的复用）。
<ol>
<li>注意：一个实例只引用一个组件，但一个组件可以被多个实例引用。
</ol>

| 属性 | 类型 | 说明 |
| ------ | ---- | ---- |
| `component` | `IComponent` | 当前实例所引用的组件。 |
| `transform` | `IMatrix` | 当前实例的变换矩阵。<ol><li>注意：当前实例可能还被上层组件包含，进而可能被更上层的实例引用而再带有变换矩阵；所以要得到</ol>  造型体的最终变换矩阵，必须把整条链路上的所有变换矩阵叠加相乘。 |
<br>

## 常量 `MIX_DATA_EXCHANGE_VERSION`

当前交换数据的版本号和历史版本号。
- 第一个为当前版本号，其余为历史版本号；

```ts
const MIX_DATA_EXCHANGE_VERSION: string[] = [
    /**
     * 当前版本号。
    */
    '0.0.1',
    /**
     * 0.0.0 - 起始占位符
    */
    '0.0.0'
];
```
<br>

## 函数 `deserialize(json: string)`

反序列化接口，把 json 文本解析成实际的数据交换对象进行返回。

- 我们提供了序列化和反序列化接口，外部用户直接使用即可，不需要关心具体的算法原理和 json 数据结构；
- json 数据的层次结构和交换数据的层次结构是基本一致的，只是属性名称进行了别名处理以及共享对象的引用通过下标来表示；
- 目前交换数据不存在历史版本号，所以反序列化流程中没有添加数据升级的过程。
- 注意：
    - 反序列化只会返回独立的顶层对象，不会返回任何子对象。
    - 一般情况下，传递的顶层对象都是ISubType，可以通过类型标识符来判断具体的子类型；
      如果业务组和外部用户在交换一些自定义的数据结构，并且顶层数据是如Point2，Vector3，Matrix等非ISubType类型，
      则双方需要另行约定好数据交换的格式，这一部分不在本数据交换包的管理范围内。

```ts
function deserialize(json: string): IObject | IObject[] | undefined;
```
<br>

## 函数 `serialize(entities: ISerializable[] | ISerializable)`

序列化接口，把数据对象序列化成 json 文本进行返回。
注意：
- 这个接口主要是给内部业务组使用的；外部用户如果需要再次序列化导出的数据，可以直接把数据交换对象
  强转成 ISerializable 进行处理即可，它们的实现类实际是继承和实现了 ISerializable 的。
- 子对象无需重复放入序列化列表，系统会自动检测依赖关系进行序列化导出；
  如果放入了子对象，序列化流程也不会对其重复保存，但再把json文本反序列化回来时，
  数组长度会缩短，因为去除了重复放入的子对象。
- 最终我们把转化好的交换数据列表打包到了一个 MIX 对象中，方便添加版本号等附加信息（目前只有版本号信息）。
- 反序列化接口可以直接接收 MIX 对象的 json 文本，但返回的还是一个交换数据列表，并不包含版本号信息。

```ts
function serialize(entities: ISerializable[] | ISerializable): string;
```
<br>

## 类 `MIX`

序列化时我们把交换数据列表打包到了一个 MIX 对象中，方便添加版本号等附加信息（目前只有版本号信息）。
反序列化接口可以直接接收 MIX 对象的 json 文本，但返回的还是一个交换数据列表，并不包含版本号信息，
因为反序列化总是会升级成最新数据版本。

```ts
class MIX  { ... }
```

### 公有成员

- **属性** `tp: string`

  类型标识符。

- **属性** `v: string`

  当前版本号。

- **属性** `d: readonly IDynamicObject[]`

  转化后的交换数据列表。
- 属性名称进行了别名处理、共享对象的引用通过下标来表示。

- **constructor**(jsonList: readonly IDynamicObject[])

<br>

## 函数 `createSerializer(context?: any)`

创建一个序列化和反序列化器；可以把MIx对象转成可以直接生成文本的json对象，或者把json对象翻译成MIx对象。
- 外部用户一般不需要使用，直接使用 dialize 和 serialize 接口即可。

```ts
function createSerializer(context?: any): ISerializer;
```
<br>

## 常量 `DefaultSubTypes`

具体实现类的类型名称汇总；也就是序列化时保存的'tp'字段。

```ts
const DefaultSubTypes = {
    //#region --------------- Math2 >> IGeometry ---------------------
    // 这部分几何数据类型（IGeometry）的子类别名（subtype）是从Math2当中复刻过来的；
    // 使用同样的别名，是为了让IGeometry的json文本可以和Math2通用，提高开发效率。
    Line2d_Type: 'L2',
    Line3d_Type: 'L',
    LineSeg2d_Type: 'LS2',
    LineSeg3d_Type: 'LS',
    Ray2d_Type: 'RAY2',
    Ray3d_Type: 'RAY',
    Circle2d_Type: 'CIR2',
    Circle3d_Type: 'CIR',
    Arc2d_Type: 'ARC2',
    Arc3d_Type: 'ARC',
    Ellipse2d_Type: 'ELP2',
    EllipticalArc2d_Type: 'EARC2',
    Ellipse3d_Type: 'ELP',
    EllipticalArc3d_Type: 'EARC3',
    PolylineCurve2d_Type: 'PLY2',
    PolylineCurve3d_Type: 'PLY',
    BezierCurve2d_Type: 'BEZ2',
    BezierCurve3d_Type: 'BEZ',
    NurbsCurve2d_Type: 'NBSC2',
    NurbsCurve3d_Type: 'NBSC3',
    Plane_Type: 'P',
    Cylinder_Type: 'CYL',
    Torus_Type: 'TOR',
    ExtrudedSurface_Type: 'SLE',
    TrimmedSurface_Type: 'GTS',
    RectTrimmedSurface_Type: 'RTS',
    Cone_Type: 'CON',
    NurbsSurface_Type: 'NBSS',
    CurveOnSurface_Type: 'COS',
    Curve3dOnSurfaces_Type: 'COSS',
    RevolvedSurface_Type: 'REVS',
    //#endregion

    /**
     * 一个打包数据块；包含了数据版本号和对象列表。
    */
    MIX: 'MIX',

    //#region ------------------------ MIxTopo ---------------------
    /**
     * 文本型名字。
    */
    TextName:'TN',
    /**
     * 结构化名字。
    */
    StructuredName:'STN',
    /**
     * 平面设计中的2维顶点。 
    */
    Vertex2: 'V2',
    /**
     * 平面设计中的2维边。
    */
    Edge2: 'E2', 
    /**
     * 平面设计中的2维区域。
    */
    Face2: 'F2',
    /**
     * 3维模型的顶点。
    */
    Vertex3: 'V3',
    /**
     * 3维模型的边。
    */
    Edge3: 'E3', 
    /**
     * 3维模型的面片。
    */
    Face3: 'F3',
    /**
     * 3维模型面片上的环。
    */
    Loop3: 'L3',
    /**
     * 构成环的翼边。
    */
    Fin3: 'FN3',
    /**
     * 额外标记出来的模型轮廓线。
    */
    Outline:'OTL',
    /**
     * 2维平面设计。
    */
    Geometric2dDesign: 'GM2',
    /**
     * 3维的实体造型模型。
    */
    Body: 'GM3',
    /**
     * 3维的三角网格模型。
    */
    MeshBody: 'MM',
    /**
     * 由若干个模型或者实例组合而成的模型组件。
    */
    Component: 'MG',
    /**
     * 组件的实例。
    */
    Instance: 'GI',
    /**
     * 暂未使用
    */
    Material: 'MT',
    /**
     * 暂未使用
    */
    MaterialMetaData: 'MMD',
    /**
     * 暂未使用
    */
    MaterialParameters: 'MP',
    /**
     * 暂未使用
    */
    Style: 'ST',
    /**
     * 暂未使用
    */
    PavingPattern: "PP",
    /**
     * 暂未使用
    */
    UVMapping: 'UVM',
    //#endregion
};
```
<br>

## 常量 `SubTypeConfig`

我们规定，可进行数据交换的纯几何数据类型（Curve, Surface, Point, Vector等）必须是math2当中的类型；
* 公司内部任何第二方如果同时在使用除math2以外的其他几何库，则必须把格式转换成math2类型后才能进行序列化和对外数据交换。

IGeometry的subType是从math2当中复刻过来的；
我们给IGeometry使用同样的别名，从而使得用于数据交换的json文本既可以直接转换成math2对象，也可以直接转换成IGeometry对象。
* 不是所有Math2类型都需要标记子类别名，是因为它们的实例在被其他对象引用的时候都是以最终实现类的类型来声明的，而不是基类或者接口。

在拓扑层面，Brep库的使用率并没有Math2那么高，所以对于拓扑类型，我们不强制必须是Brep库的类型才能做数据交换。
* 在这个库中，我们定义了一套更通用的，更精简的拓扑结构表达形式，我们称之为MIxTopo，它可以支持内部二方的各种自定义拓扑结构；
* 公司内部的二方如果想做对外的拓扑数据交换，那么需要把自己的拓扑结构序列化成MIxTopo的形式，再传递给第三方公司。

考虑到：
1. 第三方公司在调用这个库反序列化后，还可能会把数据修改后再传递回来；
2. 或者由于调查问题的时候，我们需要把MIxTopo结构的json反序列化成内部类型进行Debug；
我们决定在MIxTopo上，也加上一个字段subType，来标记内部具体实现类的类型。
* 但因为可能有多个第二方会接入；或者同一个第二方有多种不同业务含义的同类型拓扑对象，所以不同于Math2的subType，这里可能存在多个subType对应一种通用的MIxTopo类型。
* * 例如可能某二方的背景墙面和吊顶面是不同的实现类，而它们都是一种通用拓扑类型Face。

既然subType和MIxTopo不是一对一的，那么它就只能由第二方自己来定义和维护；
* 我们会要求所有第二方把自己的subType都配置到这个库所包含的某个文件当中，
* 当某个二方需要新增subType时，他必须先来查询这个文件，确认subType是否已经被占用。

此外，
* 对于第三方来说，如果他还需要知道具体的业务含义（例如是先前举例当中的背景墙还是吊顶面），想从properties字段上获取更多信息，
  那么就需要对应的内部二方提供一个额外的SDK来解释subType和properties；这部分不属于这个库的范畴。

```ts
const SubTypeConfig: ISubTypeInfo[] = [
    ...Object.entries(DefaultSubTypes).map(iter => {
        return getDefaultInfo(iter[1]);
    }),
    /**
     * 业务方也可以给自己的类型设置subType别名。
     *  - 假如某工具有两种对象都会被转换成MIxFace3，为了区分它们，可以注册不同的subType；
     *  - 如果不注册，那么这两种对象被转化后得到的MIxFace3对象的subType就都是默认值 = DefaultSubTypes.F3;
    */
    {
        subType: 'CustomSubType', // 注册自己的subType别名；不能和 DefaultSubTypes 中现有的别名重复，也不能和其他以注册的别名重复。
        description: 'DataExchange-Face',
        create: (): ISerializable => {
            return new Face('CustomSubType');
        }
    },
].filter(info => !!info) as ISubTypeInfo[];
```
<br>

</details>