!1138 优化:干涉检查性能,进度条,避免卡死

pull/1138/MERGE
ChenX 4 years ago
parent d3c6972bef
commit 3dfd41b98c

@ -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);
}

@ -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)

@ -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,59 +49,73 @@ export class CheckInterfereTool
entitySet.clear();
objMap.clear();
const csgCache: WeakMap<Entity, CSG> = 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;
for (let j = i + 1; j < ens.length; j++)
if (i % 50 === 0)
{
let e2 = ens[j];
await Sleep(0);
if (progressCallBack)
progressCallBack(i, ens.length);
}
if (e2.TempData && e2.TempData.Id === e1.TempData?.Id) continue;
let obb1 = this.GetOBB(e1);
let box1 = this.GetBox(e1);
let RelevanceMeats: Set<ObjectId>;
let RelevanceKnifs: Set<ObjectId>;
let RelativeHardware: Set<ObjectId>;
if (e1 instanceof Board)
{
let id = e2.Id ?? e2.TempData.Id;
if (e1.RelevanceMeats.includes(id) || e1.RelevanceKnifs.includes(id) || e1.RelativeHardware.includes(id)) continue;
RelevanceMeats = new Set(e1.RelevanceMeats);
RelevanceKnifs = new Set(e1.RelevanceKnifs);
RelativeHardware = new Set(e1.RelativeHardware);
}
let RelevanceBoards: Set<ObjectId>;
if (!e1.Id && e1.TempData?.Id)
{
let orgEn = e1.TempData.Id.Object;
if (orgEn instanceof HardwareCompositeEntity)
{
if (orgEn.RelevanceBoards.includes(e2.Id)) continue;
RelevanceBoards = new Set(orgEn.RelevanceBoards);
}
for (let j = i + 1; j < ens.length; j++)
{
let e2 = ens[j];
if (e2.TempData && e2.TempData.Id === e1.TempData?.Id) continue;
if (RelevanceMeats)
{
let id = e2.Id ?? e2.TempData.Id;
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;
let c2: CSG;
if (csgCache.has(e2))
c2 = csgCache.get(e2);
else
if (!obb1.intersectsOBB(this.GetOBB(e2)))
continue;
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<Entity, CSG> = 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
csg = Geometry2CSG(en.MeshGeometry);
this.csgCache.set(en, csg);
return csg;
}
obbCache = new Map<Entity, OBB>();
private GetOBB(e: Solid3D)
{
return Geometry2CSG(en.MeshGeometry);
let obb = this.obbCache.get(e);
if (obb) return obb;
obb = e.OBB;
this.obbCache.set(e, obb);
return obb;
}
boxCache = new Map<Entity, Box3>();
private GetBox(e: Solid3D)
{
let box = this.boxCache.get(e);
if (box) return box;
box = e.BoundingBox;
this.boxCache.set(e, box);
return box;
}
}

Loading…
Cancel
Save