# Tools API

`u-space` 提供了一组实用工具类，包括测量、剖切和标注功能。

## MeasureTool

用于 3D 场景中的距离测量、面积测量和角度测量，测量结果会以可视化线条渲染到场景中。

```typescript
import { MeasureTool } from 'u-space';

const measureTool = new MeasureTool(viewer.scene);
```

### `measureDistance(pointA, pointB, options?)`

测量两点之间的距离，并在场景中绘制连线。

```typescript
const result = measureTool.measureDistance(
  { x: 0, y: 0, z: 0 },
  { x: 5, y: 0, z: 5 },
  { lineColor: 0xffff00 },
);
console.log(result.value, result.unit); // 7.071 m
```

### `measureArea(points, options?)`

测量由 3 个或更多共面点围成的多边形面积。

```typescript
const result = measureTool.measureArea([
  { x: 0, y: 0, z: 0 },
  { x: 5, y: 0, z: 0 },
  { x: 5, y: 0, z: 5 },
  { x: 0, y: 0, z: 5 },
], { lineColor: 0x00ff00 });
console.log(result.value, result.unit); // 25 m²
```

### `measureAngle(pointA, vertex, pointC, options?)`

测量以中间点为顶点的夹角（单位：度）。

```typescript
const result = measureTool.measureAngle(
  { x: 3, y: 0, z: 0 },
  { x: 0, y: 0, z: 0 },
  { x: 0, y: 0, z: 3 },
);
console.log(result.value, result.unit); // 90 °
```

### `MeasureResult`

所有测量方法返回 `MeasureResult` 对象：

| 属性     | 类型        | 说明                               |
| :------- | :---------- | :--------------------------------- |
| `id`     | `string`    | 测量的唯一标识。                   |
| `type`   | `string`    | `'distance'` / `'area'` / `'angle'`。|
| `value`  | `number`    | 测量值。                           |
| `unit`   | `string`    | 单位（`m`、`m²`、`°`）。          |
| `points` | `Vector3[]` | 测量点坐标。                       |
| `object` | `Group`     | 场景中的可视化对象。               |

### `MeasureStyleOptions`

| 属性        | 类型                  | 默认值     | 说明         |
| :---------- | :-------------------- | :--------- | :----------- |
| `lineColor` | `ColorRepresentation` | 因方法而异 | 线条颜色。   |

### 管理方法

```typescript
measureTool.get('measure_dist_0');  // 获取指定测量
measureTool.remove('measure_dist_0'); // 移除指定测量
measureTool.removeAll();              // 清除全部
measureTool.getAll();                 // 获取所有测量结果
measureTool.dispose();                // 释放资源
```

---

## ClippingTool

提供剖切面和剖切盒功能，基于 WebGPU 的 `ClippingGroup` 实现。需要被剖切的对象必须是 `ClippingGroup` 的子节点。

```typescript
import { ClippingTool } from 'u-space';

const clippingTool = new ClippingTool(viewer.scene);

// 将场景中已有的物体移入 ClippingGroup，使其受剖切影响
clippingTool.attach();
```

### `attach()` / `detach()`

`attach()` 将场景根节点的所有子对象移入内部的 `ClippingGroup`，使其受剖切面影响。`detach()` 反向操作，将对象移回场景根节点。

也可以手动将对象添加到 `clippingTool.group` 中：

```typescript
clippingTool.group.add(myModel); // 仅 myModel 受剖切
```

### `addPlane(id, options?)`

添加一个剖切面。

```typescript
clippingTool.addPlane('cutY', {
  normal: { x: 0, y: -1, z: 0 },  // 法线方向
  constant: 1.5,                    // 距离原点的偏移
  showHelper: true,                 // 显示 Helper
  helperSize: 5,
  helperColor: 0xff0000,
});
```

#### `ClippingPlaneOptions`

| 属性          | 类型                  | 默认值             | 说明                     |
| :------------ | :-------------------- | :----------------- | :----------------------- |
| `normal`      | `{x, y, z}`          | `{x:0, y:-1, z:0}` | 法线方向。               |
| `constant`    | `number`              | `0`                | 距原点偏移。             |
| `showHelper`  | `boolean`             | `false`            | 是否显示 PlaneHelper。   |
| `helperSize`  | `number`              | `5`                | Helper 尺寸。            |
| `helperColor` | `ColorRepresentation` | `0xff0000`         | Helper 颜色。            |

### `addBox(id, box, options?)` / `addBoxFromObject(id, object, padding?, options?)`

添加由 6 个面组成的剖切盒。

```typescript
import { Box3 } from 'three/webgpu';

// 从 Box3 创建
const box = new Box3().setFromObject(myModel);
clippingTool.addBox('clipBox', box);

// 从对象创建（带边距）
clippingTool.addBoxFromObject('clipBox', myModel, 0.5);
```

### 动态调整

```typescript
clippingTool.setPlaneConstant('cutY', 2.0); // 修改剖切位置
viewer.render();
```

### Helper 控制

```typescript
clippingTool.showHelper('cutY', 5, 0xff0000);
clippingTool.hideHelper('cutY');
```

### 管理方法

```typescript
clippingTool.get('cutY');       // 获取 Plane 对象
clippingTool.removePlane('cutY'); // 移除单个
clippingTool.removeBox('clipBox'); // 移除剖切盒（6 个面）
clippingTool.removeAll();          // 移除全部
clippingTool.enable();             // 启用剖切
clippingTool.disable();            // 禁用剖切
clippingTool.dispose();            // 释放资源（对象移回场景根节点）
```

---

## AnnotationManager

管理 3D 标注，支持引线标注和 HTML 标签。配合 `CSSRenderer` 使用可实现 HTML 浮动标签。

```typescript
import { AnnotationManager } from 'u-space';

const annotationManager = new AnnotationManager(viewer.scene);
```

### `setCSSObjectFactory(factory)`

设置 CSS 对象工厂函数（来自 `CSSRenderer`），使标注可渲染为 CSS 叠加元素。

```typescript
annotationManager.setCSSObjectFactory(
  (el) => viewer.cssRenderer.createCSS2DObject(el),
);
```

### `add(id, options)`

添加一个标注。

```typescript
annotationManager.add('label-01', {
  position: { x: 0, y: 3, z: 0 },
  content: '<b>设备 A</b><br>温度: 25°C',
  labelOffset: { x: 0, y: 2, z: 0 },
  showLeaderLine: true,
  lineColor: 0xffffff,
  labelStyle: {
    background: 'rgba(0, 0, 0, 0.8)',
    padding: '8px 12px',
    borderRadius: '6px',
  },
});
```

#### `AnnotationOptions`

| 属性             | 类型                      | 默认值      | 说明                   |
| :--------------- | :------------------------ | :---------- | :--------------------- |
| `position`       | `{x, y, z}`              | —           | 标注锚点位置。         |
| `content`        | `string`                 | —           | HTML 内容。            |
| `labelOffset`    | `{x, y, z}`              | `{0, 2, 0}` | 标签相对锚点的偏移。   |
| `showLeaderLine` | `boolean`                | `true`      | 是否显示引线。         |
| `lineColor`      | `ColorRepresentation`    | `0xffffff`  | 引线颜色。             |
| `labelStyle`     | `AnnotationLabelStyle` | —      | 自定义 CSS 样式。      |

### `addText(text, position, options?)`

快捷添加纯文本标注。

```typescript
annotationManager.addText('入口', { x: 5, y: 0, z: 0 });
```

### 更新与控制

```typescript
annotationManager.updateContent('label-01', '温度: 30°C');
annotationManager.updatePosition('label-01', { x: 1, y: 3, z: 0 });
annotationManager.show('label-01');
annotationManager.hide('label-01');
annotationManager.showAll();
annotationManager.hideAll();
```

### 管理方法

```typescript
annotationManager.get('label-01');   // 获取标注对象
annotationManager.remove('label-01'); // 移除标注
annotationManager.removeAll();        // 移除全部
annotationManager.keys();             // 获取所有 ID
annotationManager.size;               // 标注数量
annotationManager.dispose();          // 释放资源
```
