--- 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` - 作用:生成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` - 返回说明: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` - 作用:生成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` - 返回说明: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` - 作用:在指定世界空间坐标周围生成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` - 返回说明: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` - 作用:在内部包围盒中生成随机体积数据 - 入参: | 参数名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `{ 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` - 返回说明:Uint8Array格式的体积数据 #### `generateRandomVolumeAroundPipe({ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255 }: TRandomVolumeAroundPipeOptions): Uint8Array` - 作用:在管道周围生成随机体积数据 - 入参: | 参数名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `{ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255 }` | `TRandomVolumeAroundPipeOptions` | 是 | 参数 `{ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255 }`,类型为 `TRandomVolumeAroundPipeOptions`。 | - 出参:`Uint8Array` - 返回说明:Uint8Array格式的体积数据 #### `generateRandomVolumeAroundPipeWithBaseData({ outerBox, pipeStart, pipeEnd, pipeRadius, size = 256, rangeMin = 0, rangeMax = 255, baseData }: TRandomVolumeAroundPipeOptions & { baseData: Uint8Array; }): Uint8Array` - 作用:在已有体积数据基础上按管道规则继续生成数据 - 入参: | 参数名 | 类型 | 必填 | 说明 | | --- | --- | --- | --- | | `{ 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` - 返回说明: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`