214 lines
14 KiB
Markdown
214 lines
14 KiB
Markdown
---
|
||
outline: [2, 3]
|
||
---
|
||
|
||
# VolumeTool
|
||
|
||
- 源文件:`packages/sdk/src/effect/volume/VolumeTool.ts`
|
||
- 文档位置:`packages/docs/api/effect/volume/VolumeTool.md`
|
||
|
||
## 类:`VolumeTool`
|
||
|
||
- 作用:体积数据工具类
|
||
|
||
### 方法
|
||
|
||
#### `remap(value: number, fromMin: number, fromMax: number, toMin = 0, toMax = 1): number`
|
||
|
||
- 作用:线性映射:将值从输入范围映射到输出范围
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `value` | `number` | 是 | 输入值 |
|
||
| `fromMin` | `number` | 是 | 输入范围最小值 |
|
||
| `fromMax` | `number` | 是 | 输入范围最大值 |
|
||
| `toMin` | `number` | 否 | 输出范围最小值(默认0) |
|
||
| `toMax` | `number` | 否 | 输出范围最大值(默认1) |
|
||
|
||
- 出参:`number`
|
||
- 返回说明:映射后的值
|
||
|
||
#### `generateVolumeData({ x, y, z, size = 256, rangeMin, rangeMax, }: { x?: number; y?: number; z?: number; size?: number; rangeMin: number; rangeMax: number; }): Uint8Array<ArrayBufferLike>`
|
||
|
||
- 作用:生成3D体积数据,使用Simplex噪声算法
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ x, y, z, size = 256, rangeMin, rangeMax, }` | `{ x?: number; y?: number; z?: number; size?: number; rangeMin: number; rangeMax: number; }` | 是 | 参数 `{ x, y, z, size = 256, rangeMin, rangeMax, }`,类型为 `{ x?: number; y?: number; z?: number; size?: number; rangeMin: number; rangeMax: number; }`。 |
|
||
|
||
- 出参:`Uint8Array<ArrayBufferLike>`
|
||
- 返回说明:Uint8Array格式的体积数据
|
||
|
||
#### `generateVolumeDataWithClearLayers({ x, y, z, size = 256, rangeMin, rangeMax, clearLayers = 0 }: { x?: number; y?: number; z?: number; size?: number; rangeMin: number; rangeMax: number; clearLayers?: number; }): Uint8Array<ArrayBufferLike>`
|
||
|
||
- 作用:生成3D体积数据并清除外层,使用Simplex噪声算法
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ x, y, z, size = 256, rangeMin, rangeMax, clearLayers = 0 }` | `{ x?: number; y?: number; z?: number; size?: number; rangeMin: number; rangeMax: number; clearLayers?: number; }` | 是 | 参数 `{ x, y, z, size = 256, rangeMin, rangeMax, clearLayers = 0 }`,类型为 `{ x?: number; y?: number; z?: number; size?: number; rangeMin: number; rangeMax: number; clearLayers?: number; }`。 |
|
||
|
||
- 出参:`Uint8Array<ArrayBufferLike>`
|
||
- 返回说明:Uint8Array格式的体积数据
|
||
|
||
#### `generateNoiseAroundPoints({ size = 256, worldOrigin, worldSize, points, rangeMin, rangeMax }: { size?: number; worldOrigin: [number, number, number]; worldSize: number; points: Array<{ position: [number, number, number]; radius: number, density: number }>; rangeMin: number; rangeMax: number; }): Uint8Array<ArrayBufferLike>`
|
||
|
||
- 作用:在指定世界空间坐标周围生成3D噪声值
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ size = 256, worldOrigin, worldSize, points, rangeMin, rangeMax }` | `{ size?: number; worldOrigin: [number, number, number]; worldSize: number; points: Array<{ position: [number, number, number]; radius: number, density: number }>; rangeMin: number; rangeMax: number; }` | 是 | 参数 `{ size = 256, worldOrigin, worldSize, points, rangeMin, rangeMax }`,类型为 `{ size?: number; worldOrigin: [number, number, number]; worldSize: number; points: Array<{ position: [number, number, number]; radius: number, density: number }>; rangeMin: number; rangeMax: number; }`。 |
|
||
|
||
- 出参:`Uint8Array<ArrayBufferLike>`
|
||
- 返回说明:Uint8Array格式的体积数据
|
||
|
||
#### `clearOuterLayers({ data, width, height, depth, layers }: { data: Uint8Array; width: number; height: number; depth: number; layers: number; }): void`
|
||
|
||
- 作用:清除体素空间最外层的数据,将其设置为0
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ data, width, height, depth, layers }` | `{ data: Uint8Array; width: number; height: number; depth: number; layers: number; }` | 是 | 参数 `{ data, width, height, depth, layers }`,类型为 `{ data: Uint8Array; width: number; height: number; depth: number; layers: number; }`。 |
|
||
|
||
- 出参:`void`
|
||
- 返回说明:无返回值。
|
||
|
||
#### `generateRandomVolumeInBox({ outerBox, innerBox, size = 256, rangeMin = 0, rangeMax = 255 }: { outerBox: THREE.Box3; innerBox: THREE.Box3; size?: number; rangeMin?: number; rangeMax?: number; }): Uint8Array<ArrayBufferLike>`
|
||
|
||
- 作用:在内部包围盒中生成随机体积数据
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ outerBox, innerBox, size = 256, rangeMin = 0, rangeMax = 255 }` | `{ outerBox: THREE.Box3; innerBox: THREE.Box3; size?: number; rangeMin?: number; rangeMax?: number; }` | 是 | 参数 `{ outerBox, innerBox, size = 256, rangeMin = 0, rangeMax = 255 }`,类型为 `{ outerBox: THREE.Box3; innerBox: THREE.Box3; size?: number; rangeMin?: number; rangeMax?: number; }`。 |
|
||
|
||
- 出参:`Uint8Array<ArrayBufferLike>`
|
||
- 返回说明:Uint8Array格式的体积数据
|
||
|
||
#### `generateRandomVolumeAroundPipe({ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255 }: TRandomVolumeAroundPipeOptions): Uint8Array<ArrayBufferLike>`
|
||
|
||
- 作用:在管道周围生成随机体积数据
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255 }` | `TRandomVolumeAroundPipeOptions` | 是 | 参数 `{ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255 }`,类型为 `TRandomVolumeAroundPipeOptions`。 |
|
||
|
||
- 出参:`Uint8Array<ArrayBufferLike>`
|
||
- 返回说明:Uint8Array格式的体积数据
|
||
|
||
#### `generateRandomVolumeAroundPipeWithBaseData({ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255, baseData }: TRandomVolumeAroundPipeOptions & { baseData: Uint8Array; }): Uint8Array<ArrayBufferLike>`
|
||
|
||
- 作用:在已有体积数据基础上按管道规则继续生成数据
|
||
|
||
- 入参:
|
||
|
||
| 参数名 | 类型 | 必填 | 说明 |
|
||
| --- | --- | --- | --- |
|
||
| `{ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255, baseData }` | `TRandomVolumeAroundPipeOptions & { baseData: Uint8Array; }` | 是 | 参数 `{ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255, baseData }`,类型为 `TRandomVolumeAroundPipeOptions & { baseData: Uint8Array; }`。 |
|
||
|
||
- 出参:`Uint8Array<ArrayBufferLike>`
|
||
- 返回说明:Uint8Array格式的体积数据
|
||
|
||
## 构造示例
|
||
|
||
- 当前 Demo 中没有直接展示 `VolumeTool` 的构造调用。
|
||
|
||
## 函数示例
|
||
|
||
### `VolumeTool.remap`
|
||
|
||
- 来源:`packages/demo/src/panels/GeothermalScene/DustConcentrationPanel.vue`
|
||
|
||
```ts
|
||
const mappedZList = new Float32Array(VOLUME_SIZE);
|
||
|
||
for (let x = 0; x < VOLUME_SIZE; x++) {
|
||
mappedXList[x] = VolumeTool.remap(x, 0, VOLUME_SIZE - 1, outerBox.min.x, outerBox.max.x);
|
||
}
|
||
for (let y = 0; y < VOLUME_SIZE; y++) {
|
||
mappedYList[y] = VolumeTool.remap(y, 0, VOLUME_SIZE - 1, outerBox.min.y, outerBox.max.y);
|
||
}
|
||
for (let z = 0; z < VOLUME_SIZE; z++) {
|
||
mappedZList[z] = VolumeTool.remap(z, 0, VOLUME_SIZE - 1, outerBox.min.z, outerBox.max.z);
|
||
}
|
||
```
|
||
|
||
### `VolumeTool.generateVolumeData`
|
||
|
||
- 来源:`packages/demo/src/panels/TunnelScene/FieldData/StrainDisplayPanel.vue`
|
||
|
||
```ts
|
||
const viewer = bus.getViewer();
|
||
const data = VolumeTool.generateVolumeData({size: 256, rangeMin: 10, rangeMax: 50});
|
||
|
||
volume = new VolumeMesh(viewer, {
|
||
name: "应变场",
|
||
size: 256,
|
||
data,
|
||
mode: VolumeRenderMode.EmissionAbsorptionModel,
|
||
clipMode: bus.clippingMode === 'single' ? 1 : 0,
|
||
scale: 4.99,
|
||
colorStops: [
|
||
{color: '#00FFFF', step: 0.2},
|
||
{color: '#0080FF', step: 0.5},
|
||
{color: '#8000FF', step: 0.7},
|
||
{color: '#FF00FF', step: 1.0},
|
||
],
|
||
});
|
||
volume.renderOrder = 1
|
||
// 如果加载面面板已打开,则启用体材质深度测试
|
||
if (bus.getLoadSurfaceExists && bus.getLoadSurfaceExists()) {
|
||
```
|
||
|
||
### `VolumeTool.generateRandomVolumeAroundPipeWithBaseData`
|
||
|
||
- 来源:`packages/demo/src/disasterFormationPanel/GoldMineScene/TemperaturePanel.vue`
|
||
|
||
```ts
|
||
try {
|
||
// 与 StressDisplayPanel 一致:通过 resources.loadRawData 加载 RAW。
|
||
data = await getTemperatureVolumeData();
|
||
data = VolumeTool.generateRandomVolumeAroundPipeWithBaseData({
|
||
outerBox: outerBox,
|
||
pipeStart: new THREE.Vector3(-0.11, 0, -2.505),
|
||
pipeEnd: new THREE.Vector3(-0.11, 0, -1.4),
|
||
pipeRadius: 0.25,
|
||
size: 256,
|
||
rangeMin: 6,
|
||
rangeMax: 53,
|
||
baseData: data
|
||
});
|
||
// 获取 RAW 后重新遍历体数据,使用 noise3d 重新生成体素值。
|
||
data = regenerateVolumeDataWithNoise3D(data, size);
|
||
} catch (error: unknown) {
|
||
// RAW 加载失败时回退为全 0 数据,保证面板不崩溃。
|
||
console.error("温度体 RAW 加载失败,已回退为默认空数据:", error);
|
||
data = new Uint8Array(size * size * size);
|
||
}
|
||
```
|
||
|
||
## Demo 参考
|
||
|
||
### `VolumeTool`
|
||
|
||
以下示例文件中可以看到该 API 的实际调用方式:
|
||
|
||
- `packages/demo/src/disasterFormationPanel/GoldMineScene/TemperaturePanel.vue`
|
||
- `packages/demo/src/panels/GeothermalScene/DustConcentrationPanel.vue`
|
||
- `packages/demo/src/panels/TunnelScene/FieldData/StrainDisplayPanel.vue`
|
||
- `packages/demo/src/panels/TunnelScene/FieldData/StressDisplayPanel.vue`
|
||
- `packages/demo/src/panels/TunnelScene/FieldData/TemperatureDisplayPanel.vue`
|
||
|