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:
@@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user