diff --git a/index.html b/index.html index 9a09715..b4d0558 100644 --- a/index.html +++ b/index.html @@ -331,7 +331,7 @@
- +
@@ -795,8 +795,8 @@ const placementWall = (divisions) => { - // 先清除旧的放置区域 - kernel.dropZone.clearAll(); + // 只清除旧的放置区域网格,不清除模型 + kernel.dropZone.clearZones(); // 生成新的放置区域(使用新的墙面参数化API) // 调整 baseY 来控制整体高度(正数向上,负数向下) diff --git a/src/babylonjs/AppDropZone.ts b/src/babylonjs/AppDropZone.ts index 9d38173..cf85319 100644 --- a/src/babylonjs/AppDropZone.ts +++ b/src/babylonjs/AppDropZone.ts @@ -26,6 +26,8 @@ export class AppDropZone { private zoneModelMap: Map = new Map(); // 墙面 -> 当前分割数 private wallDivisionsMap: Map = new Map(); + // 墙面 -> 该墙面模型对应的分割数(用于检测分割数变化) + private wallModelDivisionsMap: Map = new Map(); constructor(scene: Scene) { this.scene = scene; @@ -44,15 +46,8 @@ export class AppDropZone { * @param config 配置参数 */ generateDropZones(config: DropZoneConfig): PlacementZoneInfo[] { - // 检查每个墙面的分割数是否改变,如果改变则卸载该墙面的所有模型 + // 只记录分割数,不自动卸载模型 config.walls.forEach(wall => { - const oldDivisions = this.wallDivisionsMap.get(wall.name); - if (oldDivisions !== undefined && oldDivisions !== wall.divisions) { - // 分割数改变,卸载该墙面的所有模型 - this.unloadWallModels(wall.name); - console.log(`墙面 ${wall.name} 分割数从 ${oldDivisions} 改为 ${wall.divisions},已卸载所有模型`); - } - // 更新分割数记录 this.wallDivisionsMap.set(wall.name, wall.divisions); }); @@ -77,14 +72,17 @@ export class AppDropZone { // 卸载模型并清除映射 modelsToUnload.forEach(modelId => { this.appModel!.removeByName(modelId); - // 清除该模型的映射 - this.zoneModelMap.forEach((value, key) => { - if (value === modelId) { - this.zoneModelMap.delete(key); - } - }); }); + // 清除该墙面的所有映射 + const keysToDelete: string[] = []; + this.zoneModelMap.forEach((modelId, zoneKey) => { + if (zoneKey.startsWith(`${wallName}[`)) { + keysToDelete.push(zoneKey); + } + }); + keysToDelete.forEach(key => this.zoneModelMap.delete(key)); + if (modelsToUnload.length > 0) { console.log(`已卸载墙面 ${wallName} 的 ${modelsToUnload.length} 个模型`); } @@ -95,17 +93,33 @@ export class AppDropZone { */ recordModelPlacement(wallName: string, index: number, modelId: string): void { const zoneKey = `${wallName}[${index}]`; + const currentDivisions = this.wallDivisionsMap.get(wallName); + const modelDivisions = this.wallModelDivisionsMap.get(wallName); - // 检查该区域是否已有模型 - const existingModelId = this.zoneModelMap.get(zoneKey); - if (existingModelId && this.appModel) { - // 卸载旧模型 - console.log(`区域 ${zoneKey} 已有模型 ${existingModelId},将替换为 ${modelId}`); - this.appModel.removeByName(existingModelId); + // 检查分割数是否改变 + if (modelDivisions !== undefined && currentDivisions !== undefined && modelDivisions !== currentDivisions) { + // 分割数改变了,清空该墙面的所有旧模型 + console.log(`墙面 ${wallName} 分割数从 ${modelDivisions} 改为 ${currentDivisions},清空旧模型`); + this.unloadWallModels(wallName); + // 更新该墙面模型对应的分割数 + this.wallModelDivisionsMap.set(wallName, currentDivisions); + } else { + // 分割数没变,检查该区域是否已有模型(替换逻辑) + const existingModelId = this.zoneModelMap.get(zoneKey); + if (existingModelId && this.appModel) { + console.log(`区域 ${zoneKey} 已有模型 ${existingModelId},将替换为 ${modelId}`); + this.appModel.removeByName(existingModelId); + } + } + + // 如果是该墙面的第一个模型,记录分割数 + if (modelDivisions === undefined && currentDivisions !== undefined) { + this.wallModelDivisionsMap.set(wallName, currentDivisions); } // 记录新模型 this.zoneModelMap.set(zoneKey, modelId); + console.log(`已记录模型 ${modelId} 到区域 ${zoneKey}`); } /** @@ -150,6 +164,13 @@ export class AppDropZone { this.placementWall.hide(); } + /** + * 清除所有放置区域(只清除网格,不清除模型) + */ + clearZones(): void { + this.placementWall.clearAll(); + } + /** * 清除所有放置区域 */ @@ -164,6 +185,7 @@ export class AppDropZone { // 清除映射 this.zoneModelMap.clear(); this.wallDivisionsMap.clear(); + this.wallModelDivisionsMap.clear(); this.placementWall.clearAll(); } diff --git a/src/kernel/Adapter.ts b/src/kernel/Adapter.ts index ef7c03d..0863c89 100644 --- a/src/kernel/Adapter.ts +++ b/src/kernel/Adapter.ts @@ -309,6 +309,12 @@ export class KernelAdapter { zone.mesh.isVisible = false; }); }, + /** + * 清除所有放置区域(只清除网格,不清除模型) + */ + clearZones: (): void => { + this.mainApp.appDropZone.clearZones(); + }, /** * 清除所有放置区域 */