|
|
|
@ -1,6 +1,8 @@
|
|
|
|
|
import { Box3, Face3, Geometry, Mesh, Vector3 } from "three";
|
|
|
|
|
import { Box3, Material, Mesh } from "three";
|
|
|
|
|
import { CSG } from "../csg/core/CSG";
|
|
|
|
|
import { Geometry2CSG, Vector3DToVector3 } from "../csg/core/Geometry2CSG";
|
|
|
|
|
import { FuzzyCSGFactory } from "../csg/core/FuzzyFactory3d";
|
|
|
|
|
import { CSG2Geometry, Geometry2CSG } from "../csg/core/Geometry2CSG";
|
|
|
|
|
import { Plane } from "../csg/core/math/Plane";
|
|
|
|
|
import { ExtrudeHole } from "../DatabaseServices/3DSolid/ExtrudeHole";
|
|
|
|
|
import { SweepSolid } from "../DatabaseServices/3DSolid/SweepSolid";
|
|
|
|
|
import { Board } from "../DatabaseServices/Entity/Board";
|
|
|
|
@ -11,19 +13,27 @@ import { ObjectId } from "../DatabaseServices/ObjectId";
|
|
|
|
|
import { ProcessingGroupRecord } from "../DatabaseServices/ProcessingGroup/ProcessingGroupRecord";
|
|
|
|
|
import { TemplateLatticeRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateLatticeRecord";
|
|
|
|
|
import { TemplateWineRackRecord } from "../DatabaseServices/Template/ProgramTempate/TemplateWineRackRecord";
|
|
|
|
|
import { CanDrawHoleFuzz } from "../Geometry/DrillParse/BoardGetFace";
|
|
|
|
|
import { equaln, equalv3 } from "../Geometry/GeUtils";
|
|
|
|
|
import { OBB } from "../Geometry/OBB/obb";
|
|
|
|
|
import { PlaneExt } from "../Geometry/Plane";
|
|
|
|
|
import { ColorMaterial } from "./ColorPalette";
|
|
|
|
|
import { Log } from "./Log";
|
|
|
|
|
import { Sleep } from "./Sleep";
|
|
|
|
|
import { FixedNotZero } from "./Utils";
|
|
|
|
|
|
|
|
|
|
export type Solid3D = ExtrudeSolid | SweepSolid | ExtrudeHole;
|
|
|
|
|
|
|
|
|
|
export class CheckInterfereTool
|
|
|
|
|
{
|
|
|
|
|
constructor(public _MeshMaterial: Material = ColorMaterial.GetBasicMaterial(1))
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static _SingleInstance: CheckInterfereTool;
|
|
|
|
|
static GetInstance(): CheckInterfereTool
|
|
|
|
|
{
|
|
|
|
|
if (this._SingleInstance) return this._SingleInstance;
|
|
|
|
|
this._SingleInstance = new CheckInterfereTool;
|
|
|
|
|
return this._SingleInstance;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
entitySet: Set<Solid3D> = new Set();
|
|
|
|
|
objMap: Map<Mesh, [Solid3D, Solid3D]> = new Map();
|
|
|
|
|
GetEntitys(selectEnts: (HardwareCompositeEntity | ExtrudeSolid | SweepSolid)[])
|
|
|
|
@ -65,7 +75,7 @@ export class CheckInterfereTool
|
|
|
|
|
let e1 = ens[i];
|
|
|
|
|
let IsSkipEntity = this.IsSkipEntity(e1);
|
|
|
|
|
|
|
|
|
|
if (i % 50 === 0)
|
|
|
|
|
if (i !== 0 && i % 50 === 0)
|
|
|
|
|
{
|
|
|
|
|
await Sleep(0);
|
|
|
|
|
if (progressCallBack)
|
|
|
|
@ -118,11 +128,26 @@ export class CheckInterfereTool
|
|
|
|
|
if (!obb1.intersectsOBB(this.GetOBB(e2)))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
function EntityTypeCode(ext: Entity): 0 | 1 | 2
|
|
|
|
|
{
|
|
|
|
|
if (ext instanceof ExtrudeSolid)
|
|
|
|
|
return 1;
|
|
|
|
|
else if (ext instanceof ExtrudeHole)
|
|
|
|
|
return 2;
|
|
|
|
|
else
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
let t1 = EntityTypeCode(e1);
|
|
|
|
|
let t2 = EntityTypeCode(e2);
|
|
|
|
|
|
|
|
|
|
//#I2DXNO
|
|
|
|
|
if (e1 instanceof Board && e2 instanceof Board)
|
|
|
|
|
if (t1 > 0 && t2 > 0)
|
|
|
|
|
{
|
|
|
|
|
let [b1, b2] = [e1.Clone(), e2.Clone()];
|
|
|
|
|
if (!b1.Subtract([e2], [b1]) && !b1.IsErase && !b2.Subtract([e1], [b2]) && !b2.IsErase)
|
|
|
|
|
let [b1, b2] = [t1 === 1 ? <ExtrudeSolid>e1.Clone() : (<ExtrudeHole>e1).Convert2ExtrudeSolid(),
|
|
|
|
|
t2 === 1 ? <ExtrudeSolid>e2.Clone() : (<ExtrudeHole>e2).Convert2ExtrudeSolid()];
|
|
|
|
|
|
|
|
|
|
if (!b1.Subtract([b2]) && !b1.IsErase
|
|
|
|
|
&& !b2.Subtract([b1]) && !b2.IsErase)
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -134,97 +159,18 @@ export class CheckInterfereTool
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let c = csg1.intersect(csg2.transform1(e1.OCSInv.multiply(e2.OCS)));
|
|
|
|
|
|
|
|
|
|
if (c.polygons.length > 0)
|
|
|
|
|
{
|
|
|
|
|
let interCsg = csg1.intersect(csg2.transform1(e1.OCSInv.multiply(e2.OCSNoClone)));
|
|
|
|
|
|
|
|
|
|
let ptsMap = new Map<string, Vector3[]>();
|
|
|
|
|
let geo = new Geometry;
|
|
|
|
|
let planeSet = new Set<Plane>();
|
|
|
|
|
let f = new FuzzyCSGFactory;
|
|
|
|
|
for (let polygon of interCsg.polygons)
|
|
|
|
|
planeSet.add(f.getPlane(polygon.plane));
|
|
|
|
|
|
|
|
|
|
for (let poly of c.polygons)
|
|
|
|
|
{
|
|
|
|
|
let normal = Vector3DToVector3(poly.plane.normal);
|
|
|
|
|
if (equalv3(normal, new Vector3())) continue;
|
|
|
|
|
let p0 = Vector3DToVector3(poly.vertices[0].pos);
|
|
|
|
|
if (poly.vertices.some((v, i) =>
|
|
|
|
|
{
|
|
|
|
|
if (i === 0)
|
|
|
|
|
return false;
|
|
|
|
|
let p1 = Vector3DToVector3(v.pos);
|
|
|
|
|
return equalv3(p0, p1, 1e-2);
|
|
|
|
|
}))
|
|
|
|
|
continue;
|
|
|
|
|
|
|
|
|
|
let k = `${FixedNotZero(normal.x, 2)},${FixedNotZero(normal.y, 2)},${FixedNotZero(normal.z, 2)}`;
|
|
|
|
|
let k2 = `${FixedNotZero(-normal.x, 2)},${FixedNotZero(-normal.y, 2)},${FixedNotZero(-normal.z, 2)}`;
|
|
|
|
|
let pts = ptsMap.get(k);
|
|
|
|
|
if (!pts)
|
|
|
|
|
pts = ptsMap.get(k2);
|
|
|
|
|
|
|
|
|
|
if (!pts)
|
|
|
|
|
{
|
|
|
|
|
pts = [];
|
|
|
|
|
ptsMap.set(k, pts);
|
|
|
|
|
}
|
|
|
|
|
pts.push(...poly.vertices.map(v => Vector3DToVector3(v.pos)));
|
|
|
|
|
|
|
|
|
|
for (let v of poly.vertices)
|
|
|
|
|
{
|
|
|
|
|
v.tag = geo.vertices.length;
|
|
|
|
|
geo.vertices.push(Vector3DToVector3(v.pos));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let firstVertex = poly.vertices[0];
|
|
|
|
|
|
|
|
|
|
for (let i = poly.vertices.length - 3; i >= 0; i--)
|
|
|
|
|
{
|
|
|
|
|
let [a, b, c] = [
|
|
|
|
|
firstVertex.tag,
|
|
|
|
|
poly.vertices[i + 1].tag,
|
|
|
|
|
poly.vertices[i + 2].tag
|
|
|
|
|
];
|
|
|
|
|
let f = new Face3(a, b, c, normal);
|
|
|
|
|
|
|
|
|
|
geo.faces.push(f);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
let hasSolid = false;
|
|
|
|
|
let count = 0;
|
|
|
|
|
let plane = new PlaneExt();
|
|
|
|
|
for (let [k, pts] of ptsMap)
|
|
|
|
|
{
|
|
|
|
|
let nor = new Vector3().fromArray(k.split(",").map(s => parseFloat(s)));
|
|
|
|
|
plane.setFromNormalAndCoplanarPoint(nor, pts[0]);
|
|
|
|
|
//超过3点不在一个面上,一般可以围城实体
|
|
|
|
|
let outCount = 0;
|
|
|
|
|
for (let p of pts)
|
|
|
|
|
{
|
|
|
|
|
let dist = plane.distanceToPoint(p);
|
|
|
|
|
if (!equaln(dist, 0, CanDrawHoleFuzz))
|
|
|
|
|
{
|
|
|
|
|
outCount++;
|
|
|
|
|
if (outCount >= 3)
|
|
|
|
|
{
|
|
|
|
|
count++;
|
|
|
|
|
hasSolid = true;
|
|
|
|
|
ptsMap.delete(k);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (hasSolid)
|
|
|
|
|
{
|
|
|
|
|
//围不出一个实体的情况
|
|
|
|
|
if (ptsMap.size === 1) continue;
|
|
|
|
|
if (ptsMap.size === 0 && count <= 2) continue;
|
|
|
|
|
entitySet.add(e1);
|
|
|
|
|
entitySet.add(e2);
|
|
|
|
|
geo.applyMatrix4(e1.OCS);
|
|
|
|
|
let m = new Mesh(geo, ColorMaterial.GetBasicMaterial(1).clone());
|
|
|
|
|
objMap.set(m, [e1, e2]);
|
|
|
|
|
}
|
|
|
|
|
if (planeSet.size >= 4)//最少4个面围成一个三维实体
|
|
|
|
|
{
|
|
|
|
|
let geo = CSG2Geometry(interCsg).applyMatrix4(e1.OCSNoClone);
|
|
|
|
|
let mesh = new Mesh(geo, this._MeshMaterial);
|
|
|
|
|
objMap.set(mesh, [e1, e2]);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -234,6 +180,12 @@ export class CheckInterfereTool
|
|
|
|
|
return objMap;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Clear()
|
|
|
|
|
{
|
|
|
|
|
this.entitySet.clear();
|
|
|
|
|
this.objMap.clear();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
csgCache: Map<Entity, CSG> = new Map();
|
|
|
|
|
private GetCSG(en: Solid3D)
|
|
|
|
|
{
|
|
|
|
@ -273,5 +225,3 @@ export class CheckInterfereTool
|
|
|
|
|
return box;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
export const checkInterfereTool = new CheckInterfereTool();
|
|
|
|
|