feat: 优化测量功能架构与引擎组件

- 重构测量激活逻辑,在 Engine 组件中添加统一的 activateMeasure(mode) 方法
- 简化 MeasureDialogManager,移除冗余的 handleMeasureTypeChange 方法
- 添加 EngineManager.activateMeasure 转发方法
- 修复 loadModel 错误,正确调用 Engine 组件方法
- 为 Engine 组件设置固定背景渐变色
- MeasurePanel 初始化时触发 onModeChange 回调
- 添加 MeasureMode 共享类型定义

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
yuding
2026-01-15 14:13:13 +08:00
parent cd1f8186d0
commit f6257f5162
101 changed files with 31269 additions and 29937 deletions

View File

@@ -2,8 +2,9 @@ import type { ThemeConfig } from '../../themes/types';
import { IBimComponent } from '../../types/component';
import { themeManager } from '../../services/theme';
import type { EngineOptions, ModelLoadOptions } from './types';
import type { MeasureMode } from '../../types/measure';
// 导入第三方 SDK 的 createEngine 函数
import { createEngine as createEngineSDK } from '../../bim-engine-sdk.es.js';
import { createEngine as createEngineSDK } from '../../engine_base/bim-engine-sdk.es.js';
// 重新导出类型,方便外部引用
export type { EngineOptions, ModelLoadOptions };
@@ -35,6 +36,10 @@ export class Engine implements IBimComponent {
private _isDestroyed = false;
/** 主题订阅取消函数 */
private unsubscribeTheme: (() => void) | null = null;
/** 当前激活的测量类型 */
private currentMeasureType: MeasureMode | null = null;
/** 主测量功能是否已激活 */
private isMeasureActive: boolean = false;
/**
* 构造函数
@@ -53,7 +58,7 @@ export class Engine implements IBimComponent {
// 保存配置选项(设置默认值)
this.options = {
backgroundColor: options.backgroundColor ?? 0x1a1a1a, // 默认深色背景
backgroundColor: options.backgroundColor ?? 'linear-gradient(to bottom, rgb(214, 224, 235), rgb(246, 250, 255))', // 固定背景渐变色
version: options.version ?? 'v1', // 默认使用 v1 版本
showStats: options.showStats ?? false, // 默认不显示统计
showViewCube: options.showViewCube ?? true, // 默认显示视图立方体
@@ -76,6 +81,11 @@ export class Engine implements IBimComponent {
}
try {
// 应用背景色到容器
if (typeof this.options.backgroundColor === 'string') {
this.container.style.background = this.options.backgroundColor;
}
// 创建引擎配置对象
const engineConfig = {
containerId: this.containerId,
@@ -85,6 +95,9 @@ export class Engine implements IBimComponent {
showViewCube: this.options.showViewCube,
};
// 输出配置信息
console.log('引擎配置信息:', engineConfig);
// 调用引擎创建函数创建引擎实例
// 将 options 中的配置复制给 createEngine
this.engine = createEngineSDK(engineConfig);
@@ -115,33 +128,8 @@ export class Engine implements IBimComponent {
* 根据主题调整 3D 引擎的视觉效果(如背景色)
* @param theme 全局主题配置
*/
public setTheme(theme: ThemeConfig): void {
if (!this._isInitialized || !this.engine) {
return;
}
public setTheme(_theme: ThemeConfig): void {
// 根据主题调整背景色
// dark 主题使用深色背景light 主题使用浅色背景
let backgroundColor: number;
if (theme.name === 'dark') {
backgroundColor = 0x1a1a1a; // 深色背景
} else if (theme.name === 'light') {
backgroundColor = 0xf5f5f5; // 浅色背景
} else {
// 自定义主题,尝试从主题配置中获取背景色
// 如果主题配置中有 backgroundColor使用它否则使用默认值
backgroundColor = this.options.backgroundColor ?? 0x1a1a1a;
}
// 如果引擎支持设置背景色,则更新
if (this.engine && typeof this.engine.setBackgroundColor === 'function') {
this.engine.setBackgroundColor(backgroundColor);
} else if (this.engine && this.engine.scene) {
// 如果引擎有 scene 对象,尝试设置背景色
if (this.engine.scene.background) {
this.engine.scene.background.setHex(backgroundColor);
}
}
}
/**
@@ -173,7 +161,15 @@ export class Engine implements IBimComponent {
console.error('[Engine] Model URL is required.');
return;
}
this.engine.loader.loadModel(url, options);
this.engine.loaderModule.loadModels([url], options);
}
/**
* 回到主视角
* @returns
*/
public CameraGoHome() {
this.engine.viewCube.CameraGoHome();
}
/**
@@ -183,6 +179,181 @@ export class Engine implements IBimComponent {
return this.engine;
}
// ==================== 测量功能方法 ====================
/**
* 激活具体测量类型的统一入口(私有方法)
* @param type 测量类型
* @param activateFunc 第三方引擎的激活函数
*/
private activateMeasureType(type: MeasureMode, activateFunc: () => void): void {
// 1. 检查引擎是否初始化
if (!this._isInitialized || !this.engine) {
console.error('Cannot activate measure: engine not initialized.');
return;
}
// 2. 检查 measure 模块是否存在
if (!this.engine.measure) {
console.error('Measure module not available.');
return;
}
// 3. 如果主功能未激活,先激活主功能
if (!this.isMeasureActive) {
console.log(`激活测测量功能`);
this.engine.measure.active();
this.isMeasureActive = true;
}
// 4. 激活具体的测量类型(直接切换,不需要停用前一个)
activateFunc();
this.currentMeasureType = type;
}
/**
* 激活距离测量
*/
public activateDistanceMeasure(): void {
this.activateMeasureType('distance', () => {
console.log(`激活距离测量`);
this.engine.measure.distanceMeasure.active();
});
}
/**
* 激活最小距离测量
*/
public activateMinDistanceMeasure(): void {
this.activateMeasureType('minDistance', () => {
console.log(`激活最小距离测量`);
this.engine.measure.minDistanceMeasure.active();
});
}
/**
* 激活角度测量
*/
public activateAngleMeasure(): void {
this.activateMeasureType('angle', () => {
console.log(`激活角度测量`);
this.engine.measure.angleMeasure.active();
console.log('[Engine] Angle measure activated (placeholder)');
});
}
/**
* 激活标高测量
*/
public activateElevationMeasure(): void {
this.activateMeasureType('elevation', () => {
console.log(`激活标高测量`);
this.engine.measure.elevationMeasure.active();
});
}
/**
* 激活体积测量
*/
public activateVolumeMeasure(): void {
this.activateMeasureType('volume', () => {
console.log(`激活体积测量`);
this.engine.measure.volumeMeasure.active();
});
}
/**
* 激活激光测距
*/
public activateLaserDistanceMeasure(): void {
this.activateMeasureType('laserDistance', () => {
// TODO: 调用第三方引擎方法(当前先空着)
// this.engine.measure.laserDistanceMeasure.active();
console.log('[Engine] Laser distance measure activated (placeholder)');
});
}
/**
* 激活坡度测量
*/
public activateSlopeMeasure(): void {
this.activateMeasureType('slope', () => {
console.log(`激活坡度测量`);
this.engine.measure.slopeMeasure.active();
});
}
/**
* 激活空间体积测量
*/
public activateSpaceVolumeMeasure(): void {
this.activateMeasureType('spaceVolume', () => {
// TODO: 调用第三方引擎方法(当前先空着)
// this.engine.measure.spaceVolumeMeasure.active();
console.log('[Engine] Space volume measure activated (placeholder)');
});
}
/**
* 激活测量功能(根据类型统一入口)
* @param mode 测量类型
*/
public activateMeasure(mode: MeasureMode): void {
switch (mode) {
case 'distance':
this.activateDistanceMeasure();
break;
case 'minDistance':
this.activateMinDistanceMeasure();
break;
case 'angle':
this.activateAngleMeasure();
break;
case 'elevation':
this.activateElevationMeasure();
break;
case 'volume':
this.activateVolumeMeasure();
break;
case 'laserDistance':
this.activateLaserDistanceMeasure();
break;
case 'slope':
this.activateSlopeMeasure();
break;
case 'spaceVolume':
this.activateSpaceVolumeMeasure();
break;
}
}
/**
* 停用测量功能(关闭测量时调用)
*/
public deactivateMeasure(): void {
if (!this._isInitialized || !this.engine?.measure) {
return;
}
if (!this.isMeasureActive) {
return; // 已经是停用状态
}
console.log('停用测量功能');
this.engine.measure.disActive();
this.isMeasureActive = false;
this.currentMeasureType = null;
}
/**
* 获取当前激活的测量类型
* @returns 当前测量类型,如果未激活则返回 null
*/
public getCurrentMeasureType(): MeasureMode | null {
return this.currentMeasureType;
}
// ==================== 结束:测量功能方法 ====================
/**
* 销毁组件 (接口实现)
* 清理资源、取消订阅、销毁引擎实例
@@ -191,14 +362,22 @@ export class Engine implements IBimComponent {
if (this._isDestroyed) {
return;
}
// 停用测量功能
this.deactivateMeasure();
// 取消主题订阅
if (this.unsubscribeTheme) {
this.unsubscribeTheme();
this.unsubscribeTheme = null;
}
// 清理容器(可选,根据需求决定是否清空容器)
this.container.innerHTML = '';
// 更新状态
this.currentMeasureType = null;
this.isMeasureActive = false;
this._isDestroyed = true;
this._isInitialized = false;
}