Files
bim_engine/src/managers/engine-manager.ts

290 lines
11 KiB
TypeScript
Raw Normal View History

/**
* 3D
* 3D
*
*
* - EngineManager API
* - getEngineComponent() 访 Engine
* - Engine
*/
import { Engine, type EngineOptions, type ModelLoadOptions } from '../components/engine';
import { BaseManager } from '../core/base-manager';
import { RightKeyManager } from './right-key-manager';
import type { MenuItemConfig } from '../components/menu/item';
import { ManagerRegistry } from '../core/manager-registry';
2025-12-04 18:41:11 +08:00
/**
* 3D
* 3D API
2025-12-04 18:41:11 +08:00
*/
export class EngineManager extends BaseManager {
/** 容器元素 */
2025-12-04 18:41:11 +08:00
private container: HTMLElement;
/** 引擎组件实例 */
2025-12-08 10:02:24 +08:00
private engineInstance: Engine | null = null;
/** 右键菜单管理器 */
public rightKey: RightKeyManager | null = null;
2025-12-04 18:41:11 +08:00
constructor(container: HTMLElement, registry: ManagerRegistry) {
super(registry);
2025-12-04 18:41:11 +08:00
this.container = container;
}
/**
* Engine
* 访 Engine
* @returns Engine null
*/
public getEngineComponent(): Engine | null {
return this.engineInstance;
}
2025-12-04 18:41:11 +08:00
/**
* 3D
* @param options
2025-12-04 18:41:11 +08:00
* @returns
*/
public initialize(options?: Omit<EngineOptions, 'container'>): boolean {
2025-12-08 10:02:24 +08:00
if (this.engineInstance && this.engineInstance.isInitialized()) {
2025-12-04 18:41:11 +08:00
console.warn('[EngineManager] 3D Engine already initialized. Destroying old instance...');
2025-12-08 10:02:24 +08:00
this.engineInstance.destroy();
this.engineInstance = null;
2025-12-04 18:41:11 +08:00
}
try {
2025-12-08 10:02:24 +08:00
this.engineInstance = new Engine({
2025-12-04 18:41:11 +08:00
container: this.container,
...options,
}, this.registry);
2025-12-04 18:41:11 +08:00
2025-12-08 10:02:24 +08:00
this.engineInstance.init();
2025-12-04 18:41:11 +08:00
this.rightKey = new RightKeyManager(this.container, this.registry);
this.rightKey.registerHandler((_e) => {
const selected = this.engineInstance?.getSelectedComponent();
const items: MenuItemConfig[] = [];
if (selected) {
// 1. 构件详情
items.push({
id: 'componentDetail',
label: 'menu.componentDetail',
group: 'component',
order: 1,
divider: true,
onClick: () => {
const registry = this.registry;
registry.componentDetail?.show();
this.rightKey?.hide();
}
});
// 2. 隐藏选中构件
items.push({
id: 'hideSelected',
label: 'menu.hideSelected',
group: 'component',
order: 2,
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.hideModels(models);
}
this.rightKey?.hide();
}
});
// 3. 半透明选中构件
items.push({
id: 'transparentSelected',
label: 'menu.transparentSelected',
group: 'component',
order: 3,
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.translucentModels(models);
}
this.rightKey?.hide();
}
});
// 4. 取消半透明
items.push({
id: 'cancelTranslucent',
label: 'menu.cancelTranslucent',
group: 'component',
order: 4,
onClick: () => {
this.engineInstance?.unTranslucentModel();
this.rightKey?.hide();
}
});
// 5. 隔离选中构件(带子菜单)
items.push({
id: 'isolateSelected',
label: 'menu.isolateSelected',
group: 'component',
order: 5,
divider: true,
children: [
{
id: 'hideOthers',
label: 'menu.hideOthers',
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.isolateModels(models);
}
this.rightKey?.hide();
}
},
{
id: 'transparentOthers',
label: 'menu.transparentOthers',
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.translucentOtherModels(models);
}
this.rightKey?.hide();
}
}
]
});
// 6. 快速选择(带子菜单)
items.push({
id: 'quickSelect',
label: 'menu.quickSelect',
group: 'component',
order: 6,
children: [
{
id: 'selectSameType',
label: 'menu.selectSameType',
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.batchSelectSameTypeModel(models);
}
this.rightKey?.hide();
}
},
{
id: 'selectSameLevel',
label: 'menu.selectSameLevel',
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.batchSelectSameLevelModel(models);
}
this.rightKey?.hide();
}
},
{
id: 'selectSameLevelType',
label: 'menu.selectSameLevelType',
onClick: () => {
const models = this.engineInstance?.getHighlightModels();
if (models) {
this.engineInstance?.batchSelectSameLevelTypeModel(models);
}
this.rightKey?.hide();
}
}
]
});
// 7. 剖切盒适应
items.push({
id: 'fitSectionBox',
label: 'menu.fitSectionBox',
group: 'component',
order: 7,
onClick: () => {
this.engineInstance?.fitSectionBoxToModel();
this.rightKey?.hide();
}
});
}
// 8. 显示全部(始终显示)
items.push({
id: 'showAll',
label: 'menu.showAll',
group: 'component',
order: 8,
onClick: () => {
this.engineInstance?.showAllModels();
this.emit('menu:show-all', {});
this.rightKey?.hide();
}
});
return items;
});
2025-12-08 10:02:24 +08:00
return this.engineInstance.isInitialized();
2025-12-04 18:41:11 +08:00
} catch (error) {
console.error('[EngineManager] Failed to initialize 3D engine:', error);
2025-12-08 10:02:24 +08:00
this.engineInstance = null;
2025-12-04 18:41:11 +08:00
return false;
}
}
2025-12-04 18:41:11 +08:00
/**
*
* @returns
2025-12-04 18:41:11 +08:00
*/
public isInitialized(): boolean {
2025-12-08 10:02:24 +08:00
return this.engineInstance !== null && this.engineInstance.isInitialized();
2025-12-04 18:41:11 +08:00
}
2025-12-04 18:41:11 +08:00
/**
*
* @param urls URL
* @param options
2025-12-04 18:41:11 +08:00
*/
public loadModel(urls: string[], options?: ModelLoadOptions): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
2025-12-04 18:41:11 +08:00
return;
}
this.engineInstance.loadModel(urls, options);
2025-12-04 18:41:11 +08:00
}
/** 暂停渲染 */
public pauseRendering(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.pauseRendering();
}
/** 恢复渲染 */
public resumeRendering(): void {
if (!this.engineInstance) {
console.warn('[EngineManager] 3D Engine not initialized.');
return;
}
this.engineInstance.resumeRendering();
}
/** 销毁引擎管理器 */
2025-12-04 18:41:11 +08:00
public destroy(): void {
2025-12-08 10:02:24 +08:00
if (this.engineInstance) {
this.engineInstance.destroy();
this.engineInstance = null;
2025-12-04 18:41:11 +08:00
}
if (this.rightKey) {
this.rightKey.destroy();
this.rightKey = null;
}
super.destroy();
2025-12-04 18:41:11 +08:00
}
}