From 3dfd41b98cfe7c04302a4ceeea92bccd8a74c3a2 Mon Sep 17 00:00:00 2001 From: ChenX Date: Fri, 3 Jul 2020 14:58:50 +0800 Subject: [PATCH] =?UTF-8?q?!1138=20=E4=BC=98=E5=8C=96:=E5=B9=B2=E6=B6=89?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=80=A7=E8=83=BD,=E8=BF=9B=E5=BA=A6?= =?UTF-8?q?=E6=9D=A1,=E9=81=BF=E5=85=8D=E5=8D=A1=E6=AD=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- __test__/Interfere/interfere.test.ts | 4 +- src/Add-on/interfere.ts | 30 +++++- src/Common/InterfereUtil.ts | 138 ++++++++++++++++++--------- 3 files changed, 121 insertions(+), 51 deletions(-) diff --git a/__test__/Interfere/interfere.test.ts b/__test__/Interfere/interfere.test.ts index d79a38220..4b3213604 100644 --- a/__test__/Interfere/interfere.test.ts +++ b/__test__/Interfere/interfere.test.ts @@ -2,12 +2,12 @@ import { LoadEntityFromFileData } from "../Utils/LoadEntity.util"; import { Solid3D, checkInterfereTool } from "../../src/Common/InterfereUtil"; import { ObjectId } from "../../src/DatabaseServices/ObjectId"; -function Check(data: any, count: number) +async function Check(data: any, count: number) { let boards = LoadEntityFromFileData(data) as Solid3D[]; for (let i = 0; i < boards.length; i++) boards[i].objectId = new ObjectId(i); - checkInterfereTool.Check(boards as any[]); + await checkInterfereTool.Check(boards as any[]); expect(checkInterfereTool.objMap.size).toBe(count); } diff --git a/src/Add-on/interfere.ts b/src/Add-on/interfere.ts index 4b9bd7cab..d3506c317 100644 --- a/src/Add-on/interfere.ts +++ b/src/Add-on/interfere.ts @@ -2,17 +2,17 @@ import { Intent } from '@blueprintjs/core'; import { app } from '../ApplicationServices/Application'; import { DisposeThreeObj } from '../Common/Dispose'; -import { checkInterfereTool, Solid3D } from '../Common/InterfereUtil'; +import { checkInterfereTool } from '../Common/InterfereUtil'; import { ExtrudeSolid } from '../DatabaseServices/Entity/Extrude'; +import { HardwareCompositeEntity } from '../DatabaseServices/Hardware/HardwareCompositeEntity'; import { PromptStatus } from '../Editor/PromptResult'; import { userConfig } from '../Editor/UserConfig'; import { RenderType } from '../GraphicsSystem/RenderType'; import { InterfereModal } from '../UI/Components/Modal/InterfereModal'; +import { DownPanelStore } from '../UI/Store/DownPanelStore'; import { SweepSolid } from './../DatabaseServices/3DSolid/SweepSolid'; import { Command } from './../Editor/CommandMachine'; import { AppToaster } from './../UI/Components/Toaster'; -import { HardwareCompositeEntity } from '../DatabaseServices/Hardware/HardwareCompositeEntity'; -import { ExtrudeHole } from '../DatabaseServices/3DSolid/ExtrudeHole'; export class Interfere implements Command { @@ -31,7 +31,29 @@ export class Interfere implements Command let selectEnts = enRes.SelectSet.SelectEntityList as (HardwareCompositeEntity | ExtrudeSolid | SweepSolid)[]; - checkInterfereTool.Check(selectEnts); + //进度条 + let down = DownPanelStore.GetInstance() as DownPanelStore; + down.progress = 0.1; + + AppToaster.show({ + message: "正在计算干涉检查...", + timeout: 0 + }, 'interfere'); + + await checkInterfereTool.Check(selectEnts, (i, all) => + { + let a = i / all; + if (a - down.progress > 0.1) + down.progress = a; + }); + + AppToaster.show({ + message: "计算完成!", + timeout: 100 + }, 'interfere'); + + down.progress = 1; + let objMap = checkInterfereTool.objMap; if (objMap.size === 0) diff --git a/src/Common/InterfereUtil.ts b/src/Common/InterfereUtil.ts index 74c2e74c6..b4d77ea47 100644 --- a/src/Common/InterfereUtil.ts +++ b/src/Common/InterfereUtil.ts @@ -1,18 +1,22 @@ -import { Mesh, Vector3, Geometry, Face3 } from "three"; -import { ExtrudeSolid } from "../DatabaseServices/Entity/Extrude"; -import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid"; -import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole"; -import { Entity } from "../DatabaseServices/Entity/Entity"; +import { Box3, Face3, Geometry, Mesh, Vector3 } from "three"; import { CSG } from "../csg/core/CSG"; import { Geometry2CSG, Vector3DToVector3 } from "../csg/core/Geometry2CSG"; -import { equalv3 } from "../Geometry/GeUtils"; -import { FixedNotZero } from "./Utils"; -import { Box3Ext } from "../Geometry/Box"; -import { ColorMaterial } from "./ColorPalette"; -import { TemplateWineRackRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord"; -import { TemplateLatticeRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord"; +import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole"; +import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid"; import { Board } from "../DatabaseServices/Entity/Board"; +import { Entity } from "../DatabaseServices/Entity/Entity"; +import { ExtrudeSolid } from "../DatabaseServices/Entity/Extrude"; import { HardwareCompositeEntity } from "../DatabaseServices/Hardware/HardwareCompositeEntity"; +import { ObjectId } from "../DatabaseServices/ObjectId"; +import { TemplateLatticeRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord"; +import { TemplateWineRackRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord"; +import { Box3Ext } from "../Geometry/Box"; +import { equalv3 } from "../Geometry/GeUtils"; +import { OBB } from "../Geometry/OBB/obb"; +import { ColorMaterial } from "./ColorPalette"; +import { Log } from "./Log"; +import { Sleep } from "./Sleep"; +import { FixedNotZero } from "./Utils"; export type Solid3D = ExtrudeSolid | SweepSolid | ExtrudeHole; @@ -36,7 +40,8 @@ export class CheckInterfereTool } return ens; } - Check(selectEnts: (HardwareCompositeEntity | ExtrudeSolid | SweepSolid)[]) + + async Check(selectEnts: (HardwareCompositeEntity | ExtrudeSolid | SweepSolid)[], progressCallBack?: (index: number, all: number) => void) { let ens = this.GetEntitys(selectEnts); let entitySet = this.entitySet; @@ -44,20 +49,39 @@ export class CheckInterfereTool entitySet.clear(); objMap.clear(); - const csgCache: WeakMap = new WeakMap(); - for (let i = 0; i < ens.length; i++) { let e1 = ens[i]; if (e1.Template && (e1.Template.Object instanceof TemplateWineRackRecord || e1.Template.Object instanceof TemplateLatticeRecord)) continue; - let c1: CSG; - if (csgCache.has(e1)) - c1 = csgCache.get(e1); - else - c1 = this.GetCSG(e1); - let obb1 = e1.OBB; + if (i % 50 === 0) + { + await Sleep(0); + if (progressCallBack) + progressCallBack(i, ens.length); + } + + let obb1 = this.GetOBB(e1); + let box1 = this.GetBox(e1); + + let RelevanceMeats: Set; + let RelevanceKnifs: Set; + let RelativeHardware: Set; + if (e1 instanceof Board) + { + RelevanceMeats = new Set(e1.RelevanceMeats); + RelevanceKnifs = new Set(e1.RelevanceKnifs); + RelativeHardware = new Set(e1.RelativeHardware); + } + + let RelevanceBoards: Set; + if (!e1.Id && e1.TempData?.Id) + { + let orgEn = e1.TempData.Id.Object; + if (orgEn instanceof HardwareCompositeEntity) + RelevanceBoards = new Set(orgEn.RelevanceBoards); + } for (let j = i + 1; j < ens.length; j++) { @@ -65,38 +89,33 @@ export class CheckInterfereTool if (e2.TempData && e2.TempData.Id === e1.TempData?.Id) continue; - if (e1 instanceof Board) + if (RelevanceMeats) { let id = e2.Id ?? e2.TempData.Id; - if (e1.RelevanceMeats.includes(id) || e1.RelevanceKnifs.includes(id) || e1.RelativeHardware.includes(id)) continue; - } - if (!e1.Id && e1.TempData?.Id) - { - let orgEn = e1.TempData.Id.Object; - if (orgEn instanceof HardwareCompositeEntity) - { - if (orgEn.RelevanceBoards.includes(e2.Id)) continue; - } + if (RelevanceMeats.has(id) || RelevanceKnifs.has(id) || RelativeHardware.has(id)) continue; } + if (RelevanceBoards && RelevanceBoards.has(e2.Id)) + continue; + if (e2.Template && (e2.Template.Object instanceof TemplateWineRackRecord || e2.Template.Object instanceof TemplateLatticeRecord)) continue; - if (!obb1.intersectsOBB(e2.OBB)) + + if (!box1.intersectsBox(this.GetBox(e2))) + continue; + + if (!obb1.intersectsOBB(this.GetOBB(e2))) continue; - let c2: CSG; - if (csgCache.has(e2)) - c2 = csgCache.get(e2); - else + let csg1 = this.GetCSG(e1); + let csg2 = this.GetCSG(e2); + if (!csg1 || !csg2) { - c2 = this.GetCSG(e2); - csgCache.set(e2, c2); + Log("构造CSG错误!"); + continue; } - if (!c2) - console.error("实体CSG出错"); - - let c = c1.intersect(c2.transform1(e1.OCSInv.multiply(e2.OCS))); + let c = csg1.intersect(csg2.transform1(e1.OCSInv.multiply(e2.OCS))); if (c.polygons.length > 0) { @@ -178,20 +197,49 @@ export class CheckInterfereTool } } } + this.csgCache.clear(); + this.boxCache.clear(); + this.obbCache.clear(); return objMap; } + + csgCache: Map = new Map(); private GetCSG(en: Solid3D) { + let csg: CSG = this.csgCache.get(en); + if (csg) return csg; + if (en instanceof ExtrudeSolid) { if (!en.Id) en.CheckContourCurve(); - return en.CSG; + csg = en.CSG; } else - { - return Geometry2CSG(en.MeshGeometry); - } + csg = Geometry2CSG(en.MeshGeometry); + + this.csgCache.set(en, csg); + return csg; + } + + obbCache = new Map(); + private GetOBB(e: Solid3D) + { + let obb = this.obbCache.get(e); + if (obb) return obb; + obb = e.OBB; + this.obbCache.set(e, obb); + return obb; + } + + boxCache = new Map(); + private GetBox(e: Solid3D) + { + let box = this.boxCache.get(e); + if (box) return box; + box = e.BoundingBox; + this.boxCache.set(e, box); + return box; } }