# 设置系统模块文档 > 本文档基于 `iflow-engine` SDK 真实代码实现,说明设置系统的架构、API 和第三方预设接入方式。 ## 目录 - [1. 架构概览](#1-架构概览) - [2. 核心类型](#2-核心类型) - [3. 设置面板UI](#3-设置面板ui) - [4. API 参考](#4-api-参考) - [5. 第三方预设接入](#5-第三方预设接入) - [6. 事件系统](#6-事件系统) --- ## 1. 架构概览 设置系统采用分层架构: ``` ┌─────────────────────────────────────────────────────────┐ │ UI 层: Toolbar Setting Button │ │ -> registry.setting.toggle() │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ Manager 层: SettingDialogManager │ │ - 管理设置面板生命周期 │ │ - 维护预设列表 │ │ - 编排设置应用流程 │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 组件层: Engine (src/components/engine/index.ts) │ │ - 封装底层引擎设置能力 │ │ - 提供统一 getSettings/setSettings API │ └─────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────┐ │ 底层: iflow-engine-base │ │ - 实际 WebGL/Three.js 渲染设置 │ │ - Setting 模块 (shadow, lighting, env, etc.) │ └─────────────────────────────────────────────────────────┘ ``` ### 关键文件 | 文件 | 职责 | |------|------| | `src/managers/setting-dialog-manager.ts` | 设置对话框管理器,UI 和预设管理 | | `src/components/engine/index.ts` | 引擎组件,设置 API 实现 | | `src/components/engine/types.ts` | 设置相关类型定义 | | `src/types/events.ts` | 设置相关事件定义 | | `src/locales/zh-CN.ts` | 设置面板文案国际化 | --- ## 2. 核心类型 ### 2.1 EngineSettings - 完整设置 ```typescript interface EngineSettings { render: RenderSettings; display: DisplaySettings; environment: EnvironmentSettings; } interface RenderSettings { mode: 'simple' | 'balance' | 'advanced'; // 渲染模式 contrast: number; // 对比度 0-100 saturation: number; // 饱和度 0-100 shadowIntensity: number; // 阴影强度 0-100 lightIntensity: number; // 光照强度 0-100 gtaoIntensity: number; // GTAO 强度 0-100 } interface DisplaySettings { showEdge: boolean; // 显示边线 edgeOpacity: number; // 边线透明度 0-100 showGrid: boolean; // 显示轴网 showLevel: boolean; // 显示标高 showGround: boolean; // 显示地面 groundId: string; // 地面类型 ID groundHeight: number; // 地面高度 (米) } interface EnvironmentSettings { type: 'none' | 'hdr' | 'sky'; // 环境类型 hdrId: string; // HDR 背景 ID hdrIntensity: number; // HDR 强度 0-100 skyPreset: string; // 天空预设 skyParams: SkyParams; // 天空高级参数 skyIntensity: number; // 天空强度 0-100 } interface SkyParams { turbidity?: number; rayleigh?: number; mieCoefficient?: number; mieDirectionalG?: number; elevation?: number; azimuth?: number; exposure?: number; orthoExposureScale?: number; cloudCoverage?: number; cloudDensity?: number; cloudElevation?: number; showSunDisc?: boolean; } ``` ### 2.2 EngineSettingPreset - 预设定义 ```typescript interface EngineSettingPreset { id: string; // 唯一标识 presetName: string; // 预设显示名称 isDefault: boolean; // 是否为默认预设 settings: EngineSettings; // 预设包含的设置 readonly?: boolean; // 是否只读 source?: 'sdk-default' | 'external' | 'user'; // 预设来源 } ``` **source 字段说明:** - `'sdk-default'`: SDK 内置的默认预设 - `'external'`: 第三方注入的预设 - `'user'`: 用户自行保存的预设 ### 2.3 设置补丁 (局部更新) ```typescript interface EngineSettingsPatch { render?: Partial; display?: Partial; environment?: Partial; } ``` ### 2.4 预设资源列表 ```typescript interface SettingPresetLists { ground: PresetListItem[]; // 地面类型列表 hdr: PresetListItem[]; // HDR 背景列表 sky: PresetListItem[]; // 天空预设列表 } interface PresetListItem { id: string; names: string[]; // [中文名, 繁体名, 英文名] } ``` --- ## 3. 设置面板UI ### 3.1 面板结构 设置对话框宽度 `420px`,包含以下区域: ``` ┌───────────────────────────────────────────┐ │ 设置 [×] │ ← 标题栏 ├───────────────────────────────────────────┤ │ │ │ ▓▓ 渲染设置 ▓▓ │ │ 渲染模式: [性能] [平衡] [效果] │ │ 阴影强度: [══════════════●══] 75 │ │ 光照强度: [════════●═══════] 50 │ │ 对比度: [════════●═══════] 50 (效果模式可见) │ 饱和度: [════════●═══════] 50 (效果模式可见) │ GTAO: [════════●═══════] 50 (效果模式可见) │ │ │ ▓▓ 显示设置 ▓▓ │ │ 边线 [◉] 透明度 [═══●═══] 50 │ │ 轴网 [◉] │ │ 标高 [◉] │ │ 地面 [◉] 类型 [地面一 ▼] 高度 [0] │ │ │ │ ▓▓ 环境背景 ▓▓ │ │ [无] [HDR背景] [天空盒] │ │ HDR: [hdr-001 ▼] 强度 [══●═══] 40 │ │ 或 │ │ 天空: [晴朗 ▼] 强度 [══●═══] 40 │ │ │ ├───────────────────────────────────────────┤ │ [撤销修改] │ ← 修改时显示 │ [预设选择 ▼] [🗑] [保存预设] │ ← 底部操作栏 └───────────────────────────────────────────┘ ``` ### 3.2 UI 交互规则 1. **渲染模式条件显示**: - `contrast`, `saturation`, `gtaoIntensity` 仅在 `advanced` 模式下显示 - 切换模式时面板不抖动,控件平滑显示/隐藏 2. **环境类型互斥**: - `none`: 无环境背景 - `hdr`: 显示 HDR 选择器和强度滑块 - `sky`: 显示天空预设选择器和强度滑块 3. **显示设置联动**: - 边线开启后才显示透明度滑块 - 地面开启后才显示地面类型和高度输入 --- ## 4. API 参考 ### 4.1 SettingDialogManager 文件: `src/managers/setting-dialog-manager.ts` #### 生命周期 ```typescript // 初始化设置管理器 init(): void // 销毁设置管理器 destroy(): void ``` #### 对话框控制 ```typescript // 显示设置对话框 show(): void // 隐藏设置对话框 hide(): void // 切换显示状态 toggle(): void // 获取对话框是否打开 isOpen(): boolean ``` #### 预设管理 ```typescript /** * 设置/注入预设列表 * @param presets 预设数组,会合并到现有预设列表 */ setPresetList(presets: EngineSettingPreset[]): void // 获取当前预设列表 getPresetList(): EngineSettingPreset[] // 获取当前选中的预设 getSelectedPreset(): EngineSettingPreset | null // 应用指定 ID 的预设 applyPresetById(id: string): Promise ``` ### 4.2 Engine 组件设置 API 文件: `src/components/engine/index.ts` #### 批量设置 ```typescript /** * 获取当前完整设置 * @returns 当前 EngineSettings 的深拷贝 */ getSettings(): EngineSettings /** * 应用设置补丁 * @param patch 部分设置,会合并到当前设置 * @returns Promise,设置应用完成后 resolve */ setSettings(patch: EngineSettingsPatch): Promise /** * 重置为默认设置 * @returns Promise */ resetToDefault(): Promise ``` #### 预设资源 ```typescript /** * 获取预设资源列表(地面/HDR/天空) * @returns 各类资源的可用选项 */ getPresetLists(): SettingPresetLists ``` #### 渲染模式 ```typescript // 获取当前渲染模式 getRenderMode(): 'simple' | 'balance' | 'advanced' // 设置渲染模式 setRenderMode(mode: 'simple' | 'balance' | 'advanced'): void ``` #### 光照与渲染 ```typescript // 环境光强度 setAmbientLightIntensity(intensity: number): void // 0-100 getAmbientLightIntensity(): number // 对比度 setSceneContrast(contrast: number): void // 0-100 getSceneContrast(): number // 饱和度 setSceneSaturation(saturation: number): void // 0-100 getSceneSaturation(): number // 阴影强度 setShadowIntensity(intensity: number): void // 0-100 ``` #### 边线 ```typescript // 启用边线 activeModelEdge(): void // 禁用边线 disActiveModelEdge(): void // 获取边线是否启用 getModelEdgeActive(): boolean // 设置边线透明度 setEdgeOpacity(opacity: number): void // 0-100 ``` #### HDR 背景 ```typescript // 获取 HDR 列表 getHDRBackgroundList(): { name: string; id: string }[] // 设置 HDR ID setHDRBackgroundId(id: string): void // 获取当前 HDR ID getHDRBackgroundId(): string // 设置 HDR 可见性 setHDRBackgroundVisibility(visible: boolean): void // 设置 HDR 强度 setHDRIntensity(intensity: number): void // 0-100 ``` #### 地面 ```typescript // 获取地面列表 getGroundList(): { name: string; id: string }[] // 设置地面 ID setGroundId(id: string): void // 获取当前地面 ID getGroundId(): string // 设置地面高度 setGroundElevation(elevation: number): void // 米 // 获取地面高度 getGroundElevation(): number // 设置地面可见性 setGroundVisible(visible: boolean): void ``` #### 天空 ```typescript // 获取天空预设列表 getSkyPresetList(): { name: string; id: string }[] // 设置天空预设 setSkyPreset(presetId: string): void // 设置天空强度 setSkyIntensity(intensity: number): void // 0-100 // 设置天空参数 setSkyParams(params: Partial): void ``` ### 4.3 BimEngine 快捷访问 ```typescript const bimEngine = new BimEngine(container, options); // 初始化设置管理器 bimEngine.initSetting(); // 访问设置管理器 bimEngine.setting?.show(); bimEngine.setting?.hide(); bimEngine.setting?.toggle(); // 通过引擎组件访问设置 API bimEngine.engine?.getSettings(); bimEngine.engine?.setSettings({ render: { mode: 'advanced' } }); ``` --- ## 5. 第三方预设接入 ### 5.1 注入预设 第三方可通过 `setPresetList` 方法注入自定义预设: ```typescript import { BimEngine } from 'iflow-engine'; // 创建引擎 const bimEngine = new BimEngine(container, { locale: 'zh-CN', theme: 'dark' }); // 初始化必要组件 bimEngine.initToolbar(); bimEngine.initButtonGroup(); bimEngine.initDialog(); bimEngine.initEngine(); bimEngine.initSetting(); // 初始化设置管理器 // 注入第三方预设 const externalPresets = [ { id: 'vendor-indoor', presetName: '室内展厅', isDefault: false, source: 'external', // 标记为外部来源 settings: { render: { mode: 'advanced', contrast: 55, saturation: 60, shadowIntensity: 70, lightIntensity: 80, gtaoIntensity: 60, }, display: { showEdge: true, edgeOpacity: 40, showGrid: false, showLevel: true, showGround: true, groundId: 'marble-01', groundHeight: 0, }, environment: { type: 'hdr', hdrId: 'interior-01', hdrIntensity: 30, skyPreset: 'sunrise_clear', skyParams: {}, skyIntensity: 20, }, }, }, { id: 'vendor-outdoor', presetName: '室外建筑', isDefault: true, // 设为默认预设 source: 'external', settings: { render: { mode: 'balance', contrast: 50, saturation: 50, shadowIntensity: 50, lightIntensity: 50, gtaoIntensity: 50, }, display: { showEdge: false, edgeOpacity: 30, showGrid: true, showLevel: false, showGround: true, groundId: 'grass-01', groundHeight: 0, }, environment: { type: 'sky', hdrId: '0', hdrIntensity: 20, skyPreset: 'sunny_clear', skyParams: { turbidity: 3, cloudCoverage: 0.2, }, skyIntensity: 25, }, }, }, ]; bimEngine.setting?.setPresetList(externalPresets); ``` ### 5.2 预设合并规则 调用 `setPresetList` 时的处理逻辑: 1. **保留内置预设**:`__internal-default-preset__` 始终保留 2. **去重**:相同 `id` 的预设会被新传入的替换 3. **来源标记**:建议第三方预设标记 `source: 'external'` 4. **默认预设**: - 若传入的预设中有 `isDefault: true`,则选中该预设 - 若有多个 `isDefault: true`,取第一个 - 若没有指定默认,选中内置默认预设 ### 5.3 动态更新预设 ```typescript // 随时可以更新预设列表 bimEngine.setting?.setPresetList([ { id: 'dynamic-preset', presetName: '动态预设', isDefault: false, source: 'external', settings: { /* ... */ }, }, ]); // 获取当前预设列表 const presets = bimEngine.setting?.getPresetList(); ``` ### 5.4 完整示例 ```typescript import { BimEngine } from 'iflow-engine'; import type { EngineSettingPreset } from 'iflow-engine'; class VendorPresetManager { private engine: BimEngine; constructor(engine: BimEngine) { this.engine = engine; } // 注册供应商预设 registerVendorPresets() { const presets: EngineSettingPreset[] = [ this.createReviewPreset(), this.createPresentationPreset(), this.createPerformancePreset(), ]; this.engine.setting?.setPresetList(presets); } // 评审模式 - 高对比度,显示边线 private createReviewPreset(): EngineSettingPreset { return { id: 'vendor-review', presetName: '评审模式', isDefault: false, source: 'external', settings: { render: { mode: 'advanced', contrast: 70, saturation: 55, shadowIntensity: 65, lightIntensity: 55, gtaoIntensity: 50, }, display: { showEdge: true, edgeOpacity: 50, showGrid: true, showLevel: true, showGround: true, groundId: 'grid-01', groundHeight: 0, }, environment: { type: 'hdr', hdrId: 'studio-01', hdrIntensity: 35, skyPreset: 'sunrise_clear', skyParams: {}, skyIntensity: 20, }, }, }; } // 展示模式 - 高饱和度,HDR环境 private createPresentationPreset(): EngineSettingPreset { return { id: 'vendor-presentation', presetName: '展示模式', isDefault: true, // 设为默认 source: 'external', settings: { render: { mode: 'advanced', contrast: 55, saturation: 75, shadowIntensity: 80, lightIntensity: 70, gtaoIntensity: 60, }, display: { showEdge: false, edgeOpacity: 30, showGrid: false, showLevel: false, showGround: true, groundId: 'pavement-01', groundHeight: -0.5, }, environment: { type: 'hdr', hdrId: 'outdoor-afternoon', hdrIntensity: 45, skyPreset: 'sunset_glow', skyParams: {}, skyIntensity: 25, }, }, }; } // 性能模式 - 低画质,高帧率 private createPerformancePreset(): EngineSettingPreset { return { id: 'vendor-performance', presetName: '性能模式', isDefault: false, source: 'external', settings: { render: { mode: 'simple', contrast: 50, saturation: 50, shadowIntensity: 20, lightIntensity: 50, gtaoIntensity: 0, }, display: { showEdge: false, edgeOpacity: 30, showGrid: false, showLevel: false, showGround: false, groundId: '0', groundHeight: 0, }, environment: { type: 'none', hdrId: '0', hdrIntensity: 20, skyPreset: 'sunrise_clear', skyParams: {}, skyIntensity: 20, }, }, }; } } // 使用 const bimEngine = new BimEngine(container); bimEngine.initToolbar(); bimEngine.initButtonGroup(); bimEngine.initDialog(); bimEngine.initEngine(); bimEngine.initSetting(); const presetManager = new VendorPresetManager(bimEngine); presetManager.registerVendorPresets(); // 监听预设变更 bimEngine.on('setting:preset-changed', ({ preset }) => { console.log(`已切换到: ${preset.presetName}`); // 可以在这里做自定义逻辑 if (preset.source === 'external') { console.log('使用第三方预设'); } }); ``` --- ## 6. 事件系统 ### 6.1 设置相关事件 文件: `src/types/events.ts` ```typescript // 预设保存事件 'setting:preset-saved': { preset: EngineSettingPreset; // 被保存的预设 currentSettings: EngineSettings; // 当前完整设置 timestamp: number; } // 预设切换事件 'setting:preset-changed': { preset: EngineSettingPreset; // 切换后的目标预设 timestamp: number; } // 预设删除事件 'setting:preset-deleted': EngineSettingPreset; // 被删除的预设 ``` ### 6.2 事件监听示例 ```typescript const bimEngine = new BimEngine(container); // 监听预设保存 const offSaved = bimEngine.on('setting:preset-saved', ({ preset, currentSettings, timestamp }) => { console.log('用户保存预设:', preset.presetName); console.log('预设来源:', preset.source); console.log('保存时间:', new Date(timestamp)); // 可以持久化到本地存储或后端 localStorage.setItem(`preset_${preset.id}`, JSON.stringify(preset)); }); // 监听预设切换 const offChanged = bimEngine.on('setting:preset-changed', ({ preset, timestamp }) => { console.log('预设已切换:', preset.presetName); // 根据来源做不同处理 switch (preset.source) { case 'sdk-default': console.log('使用 SDK 默认预设'); break; case 'external': console.log('使用第三方预设'); break; case 'user': console.log('使用用户自定义预设'); break; } }); // 监听预设删除 const offDeleted = bimEngine.on('setting:preset-deleted', (preset) => { console.log('预设已删除:', preset.presetName); // 清理本地存储 localStorage.removeItem(`preset_${preset.id}`); }); // 取消监听 // offSaved(); // offChanged(); // offDeleted(); ``` ### 6.3 与第三方系统集成 ```typescript // 示例:将用户保存的预设同步到后端 class PresetSyncService { constructor(private engine: BimEngine) { this.setupListeners(); } private setupListeners() { // 保存时同步到后端 this.engine.on('setting:preset-saved', async ({ preset }) => { if (preset.source === 'user') { await this.saveToServer(preset); } }); // 切换时上报埋点 this.engine.on('setting:preset-changed', ({ preset }) => { this.trackPresetUsage(preset); }); } private async saveToServer(preset: EngineSettingPreset) { try { await fetch('/api/presets', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(preset), }); } catch (error) { console.error('同步预设失败:', error); } } private trackPresetUsage(preset: EngineSettingPreset) { // 埋点上报 analytics.track('Preset Changed', { presetId: preset.id, presetName: preset.presetName, source: preset.source, }); } } ``` --- ## 7. 默认值参考 ```typescript const DEFAULT_SETTINGS: EngineSettings = { render: { mode: 'advanced', contrast: 50, saturation: 50, shadowIntensity: 50, lightIntensity: 50, gtaoIntensity: 50, }, display: { showEdge: false, edgeOpacity: 30, showGrid: false, showLevel: false, showGround: false, groundId: '0', groundHeight: 0, }, environment: { type: 'none', hdrId: '0', hdrIntensity: 20, skyPreset: 'sunrise_clear', skyParams: {}, skyIntensity: 20, }, }; ``` --- ## 8. 常见问题 ### Q1: 如何获取当前生效的设置? ```typescript const currentSettings = bimEngine.engine?.getSettings(); console.log(currentSettings.render.mode); ``` ### Q2: 如何只修改部分设置? ```typescript // 只修改渲染模式,其他保持不变 await bimEngine.engine?.setSettings({ render: { mode: 'simple' } }); ``` ### Q3: 第三方预设会被用户删除吗? 不会。`readonly: true` 的预设不会显示删除按钮。建议第三方预设设置 `readonly: true`: ```typescript { id: 'vendor-preset', presetName: '供应商预设', source: 'external', readonly: true, // 用户不可删除 settings: { ... } } ``` ### Q4: 如何清空所有第三方预设? ```typescript // 获取当前列表 const currentList = bimEngine.setting?.getPresetList() || []; // 过滤掉外部预设 const filteredList = currentList.filter(p => p.source !== 'external'); // 重新设置 bimEngine.setting?.setPresetList(filteredList); ``` ### Q5: 设置修改后立即生效吗? `setSettings` 返回 Promise,设置应用完成后 resolve: ```typescript await bimEngine.engine?.setSettings({ environment: { type: 'hdr', hdrId: 'hdr-01' } }); // 到这里设置已生效 ``` --- **文档版本**: 1.0.0 **更新时间**: 2026-03-30 **适用 SDK 版本**: iflow-engine >= 2.2.0