diff --git a/src/components/engine/index.ts b/src/components/engine/index.ts index 829065b..3bc4a45 100644 --- a/src/components/engine/index.ts +++ b/src/components/engine/index.ts @@ -5,6 +5,8 @@ import type { EngineOptions, ModelLoadOptions } from './types'; import type { MeasureMode } from '../../types/measure'; // 导入第三方 SDK 的 createEngine 函数(从 npm 包引入) import { createEngine as createEngineSDK } from 'iflow-engine-base'; +// import { createEngine as createEngineSDK } from '../../../../bim_engine_base/dist/bim-engine-sdk.es'; + // 重新导出类型,方便外部引用 export type { EngineOptions, ModelLoadOptions }; @@ -40,6 +42,8 @@ export class Engine implements IBimComponent { private currentMeasureType: MeasureMode | null = null; /** 主测量功能是否已激活 */ private isMeasureActive: boolean = false; + /** 当前激活的剖切轴向 */ + private currentSectionAxis: 'x' | 'y' | 'z' | null = null; /** * 构造函数 @@ -201,6 +205,17 @@ export class Engine implements IBimComponent { this.engine.resumeRendering(); } + /** + * 销毁 3D 引擎,释放 GPU 资源 + */ + public dispose(): void { + if (!this._isInitialized || !this.engine) { + console.warn('[Engine] Engine not initialized.'); + return; + } + this.engine.dispose(); + } + // ==================== 测量功能方法 ==================== /** @@ -221,9 +236,8 @@ export class Engine implements IBimComponent { return; } - // 3. 如果主功能未激活,先激活主功能 if (!this.isMeasureActive) { - console.log(`激活测测量功能`); + console.log('激活测量功能'); this.engine.measure.active(); this.isMeasureActive = true; } @@ -249,7 +263,7 @@ export class Engine implements IBimComponent { public activateMinDistanceMeasure(): void { this.activateMeasureType('minDistance', () => { console.log(`激活最小距离测量`); - this.engine.measure.minDistanceMeasure.active(); + this.engine.measure.clearDistanceMeasure.active(); }); } @@ -280,7 +294,7 @@ export class Engine implements IBimComponent { public activateVolumeMeasure(): void { this.activateMeasureType('volume', () => { console.log(`激活体积测量`); - this.engine.measure.volumeMeasure.active(); + this.engine.measure.areaMeasure.active(); }); } @@ -358,8 +372,9 @@ export class Engine implements IBimComponent { } if (!this.isMeasureActive) { - return; // 已经是停用状态 + return; } + console.log('停用测量功能'); this.engine.measure.disActive(); this.isMeasureActive = false; @@ -374,8 +389,128 @@ export class Engine implements IBimComponent { return this.currentMeasureType; } + /** + * 清除所有测量标注 + */ + public clearAllMeasures(): void { + if (!this._isInitialized || !this.engine?.measure) { + return; + } + console.log('清除所有测量标注'); + this.engine.measure.clearAll(); + } + // ==================== 结束:测量功能方法 ==================== + // ==================== 轴向剖切功能 ==================== + + /** + * 激活轴向剖切 + * @param axis 要激活的轴向 ('x' | 'y' | 'z') + * @remarks + * - 如果传入的轴向与当前激活的轴向相同,则静默返回(幂等操作) + * - 如果当前有不同的轴向激活,先调用该轴向的 disActive() 再激活新轴向 + * - 使用单个 plane 的 disActive() 而非 clipping.disActive(),避免影响其他剖切功能 + * - 如果引擎未初始化或 clipping 模块不可用,方法会静默返回并输出错误日志 + */ + public activateSectionAxis(axis: 'x' | 'y' | 'z'): void { + // 1. 检查引擎初始化 + if (!this._isInitialized || !this.engine) { + console.error('[Engine] Cannot activate section axis: engine not initialized.'); + return; + } + + // 2. 检查 clipping 模块 + if (!this.engine.clipping) { + console.error('[Engine] Clipping module not available.'); + return; + } + + // 3. 如果是同一轴向,静默返回(幂等操作) + if (this.currentSectionAxis === axis) { + console.log(`[Engine] Section axis ${axis} already active, skipping.`); + return; + } + + // 4. 如果当前有激活的轴向且不同,先停用当前轴向 + if (this.currentSectionAxis) { + this.deactivateCurrentSectionAxis(); + } + + // 5. 激活新轴向 + const planeMap: Record<'x' | 'y' | 'z', any> = { + 'x': this.engine.clipping.sectionPlaneX, + 'y': this.engine.clipping.sectionPlaneY, + 'z': this.engine.clipping.sectionPlaneZ + }; + const plane = planeMap[axis]; + + if (plane && typeof plane.active === 'function') { + console.log(`[Engine] Activating section axis: ${axis}`); + plane.active(); + this.currentSectionAxis = axis; + } else { + console.error(`[Engine] Section plane ${axis} not available.`); + } + } + + /** + * 停用当前轴向剖切(内部方法) + * @remarks 只停用当前激活的单个轴向,不影响其他剖切功能 + */ + private deactivateCurrentSectionAxis(): void { + if (!this.currentSectionAxis || !this.engine?.clipping) { + return; + } + + const planeMap: Record<'x' | 'y' | 'z', any> = { + 'x': this.engine.clipping.sectionPlaneX, + 'y': this.engine.clipping.sectionPlaneY, + 'z': this.engine.clipping.sectionPlaneZ + }; + const plane = planeMap[this.currentSectionAxis]; + + if (plane && typeof plane.disActive === 'function') { + console.log(`[Engine] Deactivating section axis: ${this.currentSectionAxis}`); + plane.disActive(); + } + } + + /** + * 停用轴向剖切(公共方法,关闭弹窗时调用) + * @remarks 使用 clipping.disActive() 停用所有剖切,清理状态 + */ + public deactivateSectionAxis(): void { + if (!this._isInitialized || !this.engine?.clipping) { + return; + } + + if (this.currentSectionAxis) { + console.log('[Engine] Deactivating all section axis'); + this.engine.clipping.disActive(); + this.currentSectionAxis = null; + } + } + + /** + * 获取当前剖切轴向 + * @returns 当前激活的轴向,如果未激活则返回 null + */ + public getCurrentSectionAxis(): 'x' | 'y' | 'z' | null { + return this.currentSectionAxis; + } + + // ==================== 结束:轴向剖切功能 ==================== + + /** 激活框选放大功能 */ + public activateZoomBox(): void { + if (!this._isInitialized || !this.engine) { + console.warn('[Engine] Engine not initialized.'); + return; + } + this.engine.rangeScale?.active(); + } + /** * 销毁组件 (接口实现) * 清理资源、取消订阅、销毁引擎实例 @@ -394,7 +529,13 @@ export class Engine implements IBimComponent { this.unsubscribeTheme = null; } - // 清理容器(可选,根据需求决定是否清空容器) + // 销毁 3D 引擎,释放 GPU 资源 + if (this.engine) { + this.engine.dispose(); + this.engine = null; + } + + // 清理容器 this.container.innerHTML = ''; // 更新状态 diff --git a/src/managers/engine-manager.ts b/src/managers/engine-manager.ts index 29b3003..b313932 100644 --- a/src/managers/engine-manager.ts +++ b/src/managers/engine-manager.ts @@ -154,6 +154,56 @@ export class EngineManager extends BaseManager { return this.engineInstance.getCurrentMeasureType(); } + /** 清除所有测量标注 */ + public clearAllMeasures(): void { + if (!this.engineInstance) { + return; + } + this.engineInstance.clearAllMeasures(); + } + + /** + * 激活轴向剖切 + * @param axis 要激活的轴向 ('x' | 'y' | 'z') + */ + public activateSectionAxis(axis: 'x' | 'y' | 'z'): void { + if (!this.engineInstance) { + console.warn('[EngineManager] 3D Engine not initialized.'); + return; + } + this.engineInstance.activateSectionAxis(axis); + } + + /** + * 停用轴向剖切 + */ + public deactivateSectionAxis(): void { + if (!this.engineInstance) { + return; + } + this.engineInstance.deactivateSectionAxis(); + } + + /** + * 获取当前剖切轴向 + * @returns 当前激活的轴向 + */ + public getCurrentSectionAxis(): 'x' | 'y' | 'z' | null { + if (!this.engineInstance) { + return null; + } + return this.engineInstance.getCurrentSectionAxis(); + } + + /** 激活框选放大功能 */ + public activateZoomBox(): void { + if (!this.engineInstance) { + console.warn('[EngineManager] 3D Engine not initialized.'); + return; + } + this.engineInstance.activateZoomBox(); + } + /** 销毁引擎管理器 */ public destroy(): void { if (this.engineInstance) {