|
|
|
@ -1,7 +1,14 @@
|
|
|
|
|
import geom2, { Geom2 } from '@jscad/modeling/src/geometries/geom2';
|
|
|
|
|
import geom3, { transform } from '@jscad/modeling/src/geometries/geom3';
|
|
|
|
|
import Geom3 from '@jscad/modeling/src/geometries/geom3/type';
|
|
|
|
|
import poly3, { measureArea } from '@jscad/modeling/src/geometries/poly3';
|
|
|
|
|
import { Mat4 } from '@jscad/modeling/src/maths/mat4';
|
|
|
|
|
import subtract from '@jscad/modeling/src/operations/booleans/subtract';
|
|
|
|
|
import union from '@jscad/modeling/src/operations/booleans/union';
|
|
|
|
|
import { Vec2 } from '@jscad/modeling/src/maths/vec2';
|
|
|
|
|
import { Vec3 } from '@jscad/modeling/src/maths/vec3';
|
|
|
|
|
import { intersect, subtract, union } from '@jscad/modeling/src/operations/booleans';
|
|
|
|
|
import extrudeLinear from '@jscad/modeling/src/operations/extrusions/extrudeLinear';
|
|
|
|
|
import extrudeRotate from '@jscad/modeling/src/operations/extrusions/extrudeRotate';
|
|
|
|
|
import retessellate from '@jscad/modeling/src/operations/modifiers/retessellate';
|
|
|
|
|
import { BufferGeometry, Euler, FrontSide, Frustum, Geometry, LineSegments, Matrix3, Matrix4, Mesh, Object3D, ShapeGeometry, Line as TLine, UVGenerator, Vector3 } from 'three';
|
|
|
|
|
import { Board2Regions } from '../../Add-on/BoardEditor/Board2Regions';
|
|
|
|
|
import { DeserializationBoard2DModeingData, DeserializationBoard3DModeingData, SerializeBoard2DModeingData, SerializeBoard3DModeingData, deserializationBoardData, serializeBoardData } from '../../Add-on/BoardEditor/SerializeBoardData';
|
|
|
|
@ -14,19 +21,23 @@ import { EBoardKeyList } from '../../Common/BoardKeyList';
|
|
|
|
|
import { Geom3Res } from '../../Common/CSGIntersect';
|
|
|
|
|
import { ColorMaterial } from '../../Common/ColorPalette';
|
|
|
|
|
import { DisposeThreeObj } from '../../Common/Dispose';
|
|
|
|
|
import { MakeMirrorMtx, TransformVector, ZMirrorMatrix, tempMatrix1 } from '../../Common/Matrix4Utils';
|
|
|
|
|
import { MakeMirrorMtx, TransformVector, Vector2ApplyMatrix4, ZMirrorMatrix, tempMatrix1 } from '../../Common/Matrix4Utils';
|
|
|
|
|
import { UpdateDraw } from '../../Common/Status';
|
|
|
|
|
import { FixIndex } from '../../Common/Utils';
|
|
|
|
|
import { ObjectSnapMode } from '../../Editor/ObjectSnapMode';
|
|
|
|
|
import { boardUVGenerator, boardUVGenerator2 } from '../../Geometry/BoardUVGenerator';
|
|
|
|
|
import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils';
|
|
|
|
|
import { EdgesGeometry } from '../../Geometry/EdgeGeometry';
|
|
|
|
|
import { GetArcDrawCount } from '../../Geometry/ExtrudeMeshGeomBuilder/SplitCurveParams';
|
|
|
|
|
import { IdentityMtx4, XAxis, XAxisN, YAxis, YAxisN, ZAxis, ZeroVec, equaln, equalv3 } from '../../Geometry/GeUtils';
|
|
|
|
|
import { PointShapeUtils } from '../../Geometry/PointShapeUtils';
|
|
|
|
|
import { SweepGeometry } from '../../Geometry/SweepGeometry';
|
|
|
|
|
import { SweepGeometrySimple } from '../../Geometry/SweepGeometry';
|
|
|
|
|
import { GetBoardHighSeal, GetBoardSealingCurves, SetBoardTopDownLeftRightSealData } from '../../GraphicsSystem/CalcEdgeSealing';
|
|
|
|
|
import { RenderType } from '../../GraphicsSystem/RenderType';
|
|
|
|
|
import { VData2Curve, VKnifToolPath } from '../../GraphicsSystem/ToolPath/VKnifToolPath';
|
|
|
|
|
import { Max } from '../../Nest/Common/Util';
|
|
|
|
|
import { BoardProcessOption } from "../../UI/Store/OptionInterface/BoardProcessOption";
|
|
|
|
|
import { FuzzyFactory } from '../../csg/core/FuzzyFactory';
|
|
|
|
|
import { CSG2Geometry2, Geometry2CSG2 } from '../../csg/core/Geometry2CSG';
|
|
|
|
|
import { CylinderHole } from '../3DSolid/CylinderHole';
|
|
|
|
|
import { ExtrudeHole } from '../3DSolid/ExtrudeHole';
|
|
|
|
@ -45,6 +56,7 @@ import { DragPointType } from './DragPointType';
|
|
|
|
|
import { Entity } from './Entity';
|
|
|
|
|
import { ExtrudeContourCurve, ExtrudeSolid } from './Extrude';
|
|
|
|
|
import { GenLocalUv } from './GenLocalUv';
|
|
|
|
|
import { Line } from './Line';
|
|
|
|
|
import { Polyline } from './Polyline';
|
|
|
|
|
|
|
|
|
|
//排钻配置名是合法的 可用的
|
|
|
|
@ -1301,8 +1313,11 @@ export class Board extends ExtrudeSolid
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private _2DPathCsgs: Geom3[];//二维刀路的csg数组
|
|
|
|
|
private _2DPathDrawObject: Object3D;
|
|
|
|
|
//获取二维刀路的csg数组
|
|
|
|
|
private _2DPathDrawObject: Object3D;//二维刀路提刀线框显示对象
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* 这个函数生成了二维刀路的csg数组,并且同时生成了_2DPathDrawObject(二维刀路提刀线框显示对象)
|
|
|
|
|
*/
|
|
|
|
|
private Get2DPathCsgs(): Geom3[]
|
|
|
|
|
{
|
|
|
|
|
if (this._2DPathCsgs)
|
|
|
|
@ -1314,63 +1329,240 @@ export class Board extends ExtrudeSolid
|
|
|
|
|
if (this._2DModelingList.length === 0)
|
|
|
|
|
return this._2DPathCsgs;
|
|
|
|
|
|
|
|
|
|
let modelKnifePtsCache: Map<string, Vec2[]> = new Map();
|
|
|
|
|
|
|
|
|
|
let tempVec = new Vector3;
|
|
|
|
|
|
|
|
|
|
for (let vm of this._2DModelingList)
|
|
|
|
|
{
|
|
|
|
|
let path = vm.path;
|
|
|
|
|
let pathGripsSet = new Set();
|
|
|
|
|
let fuzz = new FuzzyFactory;
|
|
|
|
|
|
|
|
|
|
//获取端点部分的csg(使用旋转建模)
|
|
|
|
|
const GetGripsCsgs = (pts: Vector3[], geom3s: Geom3[], knifeGeom: Geom2, knifeGeomRadius: number) =>
|
|
|
|
|
{
|
|
|
|
|
for (let pt of pts)
|
|
|
|
|
{
|
|
|
|
|
let key = fuzz.lookupOrCreate([pt.x, pt.y], pt);
|
|
|
|
|
if (!pathGripsSet.has(key))
|
|
|
|
|
{
|
|
|
|
|
let rotateGeom = extrudeRotate({ segments: GetArcDrawCount(knifeGeomRadius), angle: 2 * Math.PI }, knifeGeom);
|
|
|
|
|
rotateGeom = retessellate(rotateGeom);
|
|
|
|
|
// TestDrawGeom3s([rotateGeom]);
|
|
|
|
|
let mat = new Matrix4().setPosition(pt);
|
|
|
|
|
rotateGeom = transform(mat.elements as Mat4, rotateGeom);
|
|
|
|
|
geom3s.push(rotateGeom);
|
|
|
|
|
pathGripsSet.add(key);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
for (let item of vm.items)
|
|
|
|
|
{
|
|
|
|
|
let tempPath = this.GetOffsetPath(path, item);
|
|
|
|
|
if (tempPath)
|
|
|
|
|
{
|
|
|
|
|
let sweepContour = this._KnifePolylineMap.get(item.knife.id);
|
|
|
|
|
|
|
|
|
|
if (true || !sweepContour)//如果没有轮廓的时候,我们还是依然绘制线段 (因为现在我们没有线框生成 所以强制true)
|
|
|
|
|
{
|
|
|
|
|
if (!this._2DPathDrawObject) this._2DPathDrawObject = new Object3D;
|
|
|
|
|
|
|
|
|
|
let curves = VData2Curve(VKnifToolPath(tempPath, item.depth, item.knife.angle / 2));
|
|
|
|
|
let o = new Object3D();
|
|
|
|
|
let curves = VData2Curve(VKnifToolPath(tempPath, item.depth, item.knife.angle / 2));//走刀+提刀曲线
|
|
|
|
|
let pathObject = new Object3D();//走刀路径绘制线
|
|
|
|
|
for (let c of curves)
|
|
|
|
|
{
|
|
|
|
|
c.ColorIndex = tempPath.ColorIndex;
|
|
|
|
|
o.add(c.GetDrawObjectFromRenderType(RenderType.Wireframe));
|
|
|
|
|
pathObject.add(c.GetDrawObjectFromRenderType(RenderType.Wireframe));
|
|
|
|
|
}
|
|
|
|
|
if (vm.dir === FaceDirection.Back)
|
|
|
|
|
{
|
|
|
|
|
o.applyMatrix4(ZMirrorMatrix);
|
|
|
|
|
o.position.z = item.depth;
|
|
|
|
|
pathObject.applyMatrix4(ZMirrorMatrix);
|
|
|
|
|
pathObject.position.z = item.depth;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
o.position.z = this.thickness - item.depth;
|
|
|
|
|
o.updateMatrix();
|
|
|
|
|
this._2DPathDrawObject.add(o);
|
|
|
|
|
pathObject.position.z = this.thickness - item.depth;
|
|
|
|
|
pathObject.updateMatrix();
|
|
|
|
|
this._2DPathDrawObject.add(pathObject);
|
|
|
|
|
}
|
|
|
|
|
if (!sweepContour) continue;
|
|
|
|
|
|
|
|
|
|
let geom3s: Geom3[] = [];
|
|
|
|
|
|
|
|
|
|
//刀截面轮廓Pts
|
|
|
|
|
let knifeGeomPts: Vec2[] = modelKnifePtsCache.get(item.knife.id);
|
|
|
|
|
|
|
|
|
|
if (!knifeGeomPts?.length)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
let shapePts = sweepContour.Shape.getPoints();
|
|
|
|
|
for (let p of shapePts)
|
|
|
|
|
Vector2ApplyMatrix4(sweepContour.OCSNoClone, p);
|
|
|
|
|
|
|
|
|
|
knifeGeomPts = shapePts.map(p => [p.x, p.y]);
|
|
|
|
|
|
|
|
|
|
// continue;
|
|
|
|
|
if (sweepContour.IsClockWise) knifeGeomPts.reverse();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!sweepContour) continue;
|
|
|
|
|
//刀截面geom
|
|
|
|
|
let knifeGeom = geom2.fromPoints(knifeGeomPts);
|
|
|
|
|
let knifeGeomRadius = sweepContour.BoundingBox.getSize(tempVec).y / 2;
|
|
|
|
|
|
|
|
|
|
const geometry = new SweepGeometry(sweepContour, tempPath);
|
|
|
|
|
let csg = Geometry2CSG2(geometry);
|
|
|
|
|
if (vm.dir === FaceDirection.Front)
|
|
|
|
|
//分解路径
|
|
|
|
|
let cus = tempPath.Explode();
|
|
|
|
|
|
|
|
|
|
if (item.knife.angle)
|
|
|
|
|
{
|
|
|
|
|
let mtx = new Matrix4().setPosition(0, 0, this.thickness - item.depth);
|
|
|
|
|
let sweepGeom = new SweepGeometrySimple(sweepContour, cus);
|
|
|
|
|
|
|
|
|
|
//这里我们对盖子进行精简
|
|
|
|
|
let lidPolys: poly3.Poly3[] = [];
|
|
|
|
|
|
|
|
|
|
let fuzz = new FuzzyFactory;
|
|
|
|
|
let lidVerts = sweepGeom.shapePts2d.map((p, i) =>
|
|
|
|
|
{
|
|
|
|
|
fuzz.lookupOrCreate([p.x, p.y], i);
|
|
|
|
|
return [p.x, p.y, 0] as Vec3;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (let face of sweepGeom.TriFaces)
|
|
|
|
|
lidPolys.push(poly3.create(face.map(index => lidVerts[index])));
|
|
|
|
|
|
|
|
|
|
let lidGeom3 = retessellate(geom3.create(lidPolys));
|
|
|
|
|
let lidPolygons = lidGeom3.polygons.map(p => p.vertices.map(v => fuzz.lookupOrCreate([v[0], v[1]], -1)));
|
|
|
|
|
//精简结束
|
|
|
|
|
|
|
|
|
|
//遍历每个水管
|
|
|
|
|
for (let i = 0; i < sweepGeom.SidePolygons.length; i++)
|
|
|
|
|
{
|
|
|
|
|
let polygons = sweepGeom.SidePolygons[i];
|
|
|
|
|
let polys: poly3.Poly3[] = [];
|
|
|
|
|
for (let polygon of polygons)
|
|
|
|
|
{
|
|
|
|
|
let pts = polygon.map(i => sweepGeom.vertices[i]);//这是水管盖子的点
|
|
|
|
|
|
|
|
|
|
//水管前进的方向
|
|
|
|
|
let dir = polygon["dir"] as Vector3;
|
|
|
|
|
|
|
|
|
|
//如果水管的侧面自交了,我们选择性的删掉一个无用面
|
|
|
|
|
let dir1 = tempVec.subVectors(pts[3], pts[0]).normalize();
|
|
|
|
|
if (!equalv3(dir, dir1))//如果反向1
|
|
|
|
|
{
|
|
|
|
|
let l1 = new Line(pts[0], pts[1]);
|
|
|
|
|
let l2 = new Line(pts[2], pts[3]);
|
|
|
|
|
let p = l1.IntersectWith(l2, 0)[0];
|
|
|
|
|
|
|
|
|
|
if (!p) continue;//弃用了这个多边形
|
|
|
|
|
|
|
|
|
|
// polys.push(poly3.create([vertices[3], p.toArray() as Vec3, vertices[0]]));//弃用了无效的自交三角形
|
|
|
|
|
polys.push(poly3.create([p.toArray() as Vec3, pts[1].toArray() as Vec3, pts[2].toArray() as Vec3]));
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let dir2 = tempVec.subVectors(pts[2], pts[1]).normalize();
|
|
|
|
|
if (!equalv3(dir, dir2))//如果反向2
|
|
|
|
|
{
|
|
|
|
|
let l1 = new Line(pts[0], pts[1]);
|
|
|
|
|
let l2 = new Line(pts[2], pts[3]);
|
|
|
|
|
let p = l1.IntersectWith(l2, 0)[0];
|
|
|
|
|
|
|
|
|
|
if (!p) continue;//弃用了这个多边形
|
|
|
|
|
|
|
|
|
|
polys.push(poly3.create([pts[0].toArray() as Vec3, p.toArray() as Vec3, pts[3].toArray() as Vec3]));
|
|
|
|
|
// polys.push(poly3.create([p.toArray() as Vec3, vertices[2], vertices[1]]));//弃用了无效的自交三角形
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
polys.push(poly3.create(pts.map(p => p.toArray() as Vec3)));//如果没有反向,那么我们直接返回多边形
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//构建水管的盖子
|
|
|
|
|
let curVerts = sweepGeom.shapeVerts[FixIndex(i, sweepGeom.shapeVerts)];
|
|
|
|
|
let nextVerts = sweepGeom.shapeVerts[FixIndex(i + 1, sweepGeom.shapeVerts)];
|
|
|
|
|
let lid1: poly3.Poly3[] = [];
|
|
|
|
|
let lid2: poly3.Poly3[] = [];
|
|
|
|
|
for (let lidPolygon of lidPolygons)//我们使用已经精简过的盖子索引
|
|
|
|
|
{
|
|
|
|
|
lid1.push(poly3.create(lidPolygon.map(index => curVerts[index].toArray() as Vec3)));
|
|
|
|
|
lid2.push(poly3.create(lidPolygon.reverse().map(index => nextVerts[index].toArray() as Vec3)));
|
|
|
|
|
lidPolygon.reverse();//这里偷懒了
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let edge = geometry.EdgeGeom.applyMatrix4(mtx);
|
|
|
|
|
// this._2DPathDrawObject.add(new LineSegments(edge, ColorMaterial.GetLineMaterial(this.ColorIndex)));
|
|
|
|
|
let lidGeom1 = geom3.create(lid1);
|
|
|
|
|
let lidGeom2 = geom3.create(lid2);
|
|
|
|
|
|
|
|
|
|
csg.transforms = mtx.toArray() as Mat4;
|
|
|
|
|
let intGeom = intersect(lidGeom1, lidGeom2);
|
|
|
|
|
if (intGeom.polygons.length)
|
|
|
|
|
polys.push(...intGeom.polygons);
|
|
|
|
|
else
|
|
|
|
|
polys.push(...lidGeom1.polygons, ...lidGeom2.polygons);
|
|
|
|
|
|
|
|
|
|
geom3s.push(geom3.create(polys));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//提刀轮廓 未闭合路径增加圆角 端点部分
|
|
|
|
|
if (!tempPath.IsClose)
|
|
|
|
|
GetGripsCsgs([tempPath.StartPoint, tempPath.EndPoint], geom3s, knifeGeom, knifeGeomRadius);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
let mtx = MakeMirrorMtx(ZAxis, new Vector3(0, 0, item.depth * 0.5));
|
|
|
|
|
let mt4Z = new Matrix4().makeRotationZ(Math.PI / 2);
|
|
|
|
|
let mt4Y = new Matrix4().makeRotationY(Math.PI / 2);
|
|
|
|
|
|
|
|
|
|
for (let cu of cus)
|
|
|
|
|
{
|
|
|
|
|
if (cu instanceof Line)
|
|
|
|
|
{
|
|
|
|
|
//直线部分
|
|
|
|
|
//旋转至 X为正方向
|
|
|
|
|
let lineShape = extrudeLinear({ height: cu.Length }, knifeGeom);
|
|
|
|
|
lineShape = retessellate(lineShape);
|
|
|
|
|
lineShape = transform(mt4Z.elements as Mat4, lineShape);
|
|
|
|
|
lineShape = transform(mt4Y.elements as Mat4, lineShape);
|
|
|
|
|
//平移到原点为中心
|
|
|
|
|
let mtx = new Matrix4().setPosition((new Vector3(-cu.Length / 2, 0, 0)));
|
|
|
|
|
lineShape = transform(mtx.elements as Mat4, lineShape);
|
|
|
|
|
//旋转直线正确方向
|
|
|
|
|
let pt = cu.StartPoint.sub(cu.EndPoint);
|
|
|
|
|
mtx = new Matrix4().makeRotationZ(Math.atan2(pt.y, pt.x));
|
|
|
|
|
lineShape = transform(mtx.elements as Mat4, lineShape);
|
|
|
|
|
//平移到线段中点
|
|
|
|
|
mtx = new Matrix4().setPosition(cu.Midpoint);
|
|
|
|
|
lineShape = transform(mtx.elements as Mat4, lineShape);
|
|
|
|
|
geom3s.push(lineShape);
|
|
|
|
|
|
|
|
|
|
//端点部分
|
|
|
|
|
GetGripsCsgs([cu.StartPoint, cu.EndPoint], geom3s, knifeGeom, knifeGeomRadius);
|
|
|
|
|
}
|
|
|
|
|
else if (cu instanceof Arc)
|
|
|
|
|
{
|
|
|
|
|
//弧线部分
|
|
|
|
|
//获取针对弧形扫掠Geom
|
|
|
|
|
let mt4 = new Matrix4().setPosition(cu.Radius, 0, 0);
|
|
|
|
|
let arcKnifeGeom = geom2.transform(mt4.elements as Mat4, knifeGeom);
|
|
|
|
|
let rotateGeom = extrudeRotate({ segments: GetArcDrawCount(cu.Radius), angle: cu.AllAngle }, arcKnifeGeom);
|
|
|
|
|
rotateGeom = retessellate(rotateGeom);
|
|
|
|
|
//放置Geom
|
|
|
|
|
let rotateMat = new Matrix4().makeRotationZ(cu.IsClockWise ? cu.EndAngle : cu.StartAngle).setPosition(cu.Position);
|
|
|
|
|
rotateGeom = transform(rotateMat.elements as Mat4, rotateGeom);
|
|
|
|
|
geom3s.push(rotateGeom);
|
|
|
|
|
//端点部分
|
|
|
|
|
GetGripsCsgs([cu.StartPoint, cu.EndPoint], geom3s, knifeGeom, knifeGeomRadius);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// let edge = geometry.EdgeGeom.applyMatrix4(mtx);
|
|
|
|
|
// this._2DPathDrawObject.add(new LineSegments(edge, ColorMaterial.GetLineMaterial(this.ColorIndex)));
|
|
|
|
|
let mtx: Matrix4;
|
|
|
|
|
if (vm.dir === FaceDirection.Front)
|
|
|
|
|
mtx = new Matrix4().setPosition(0, 0, this.thickness - item.depth);
|
|
|
|
|
else
|
|
|
|
|
mtx = MakeMirrorMtx(ZAxis, new Vector3(0, 0, item.depth * 0.5));
|
|
|
|
|
|
|
|
|
|
csg.transforms = mtx.toArray() as Mat4;
|
|
|
|
|
for (let geom of geom3s)
|
|
|
|
|
{
|
|
|
|
|
geom = transform(mtx.elements as Mat4, geom);
|
|
|
|
|
this._2DPathCsgs.push(geom);
|
|
|
|
|
}
|
|
|
|
|
this._2DPathCsgs.push(csg);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -1387,19 +1579,89 @@ export class Board extends ExtrudeSolid
|
|
|
|
|
override UpdateMeshGeom(geo: Geometry): BufferGeometry
|
|
|
|
|
{
|
|
|
|
|
let path2dCsgs = this.Get2DPathCsgs();
|
|
|
|
|
if (path2dCsgs.length === 0 || !HostApplicationServices.show2DPathObject)
|
|
|
|
|
if (!path2dCsgs.length || !HostApplicationServices.show2DPathObject)
|
|
|
|
|
{
|
|
|
|
|
if (geo instanceof Geometry)
|
|
|
|
|
return new BufferGeometry().fromGeometry(geo);
|
|
|
|
|
return geo;
|
|
|
|
|
}
|
|
|
|
|
// TestDrawGeom3s(path2dCsgs);
|
|
|
|
|
|
|
|
|
|
let gemUnion = path2dCsgs[0];
|
|
|
|
|
for (let i = 1; i < path2dCsgs.length; i++)
|
|
|
|
|
gemUnion = union(gemUnion, path2dCsgs[i]);
|
|
|
|
|
|
|
|
|
|
let geomSub = union(path2dCsgs);
|
|
|
|
|
let geom = Geometry2CSG2(geo);
|
|
|
|
|
let newGeom = subtract(geom, geomSub);
|
|
|
|
|
|
|
|
|
|
this._EdgeGeometry = new EdgesGeometry().FromCSG(newGeom as unknown as Geom3Res);
|
|
|
|
|
let newGeom = subtract(geom, gemUnion);
|
|
|
|
|
|
|
|
|
|
//删除小面积(只留一个)
|
|
|
|
|
{
|
|
|
|
|
let fuzz = new FuzzyFactory;
|
|
|
|
|
let vmap = new Map;
|
|
|
|
|
for (let poly of newGeom.polygons)
|
|
|
|
|
{
|
|
|
|
|
for (let v of poly.vertices)
|
|
|
|
|
{
|
|
|
|
|
let key = fuzz.lookupOrCreate(v, v);
|
|
|
|
|
let arr = vmap.get(key);
|
|
|
|
|
if (!arr)
|
|
|
|
|
{
|
|
|
|
|
arr = [];
|
|
|
|
|
vmap.set(key, arr);
|
|
|
|
|
}
|
|
|
|
|
arr.push(poly);
|
|
|
|
|
|
|
|
|
|
v["__key__"] = key;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let polys = newGeom.polygons.concat();
|
|
|
|
|
let polyGroups = [];
|
|
|
|
|
|
|
|
|
|
let calcs = new Set;
|
|
|
|
|
while (polys.length)
|
|
|
|
|
{
|
|
|
|
|
let poly1 = polys.pop();
|
|
|
|
|
calcs.add(poly1);
|
|
|
|
|
let polyGroup = [poly1];
|
|
|
|
|
polyGroups.push(polyGroup);
|
|
|
|
|
|
|
|
|
|
for (let i = 0; i < polyGroup.length; i++)
|
|
|
|
|
{
|
|
|
|
|
let poly = polyGroup[i];
|
|
|
|
|
|
|
|
|
|
for (let v of poly.vertices)
|
|
|
|
|
{
|
|
|
|
|
let key = v["__key__"];
|
|
|
|
|
let arr = vmap.get(key);
|
|
|
|
|
|
|
|
|
|
for (let vpoly of arr)
|
|
|
|
|
{
|
|
|
|
|
if (calcs.has(vpoly)) continue;
|
|
|
|
|
|
|
|
|
|
calcs.add(vpoly);
|
|
|
|
|
|
|
|
|
|
polyGroup.push(vpoly);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// arrayRemoveIf(polys, poly => !calcs.has(poly)); //加上这个无法提高性能
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let areas = polyGroups.map(polys =>
|
|
|
|
|
{
|
|
|
|
|
let area = 0;
|
|
|
|
|
for (let poly of polys)
|
|
|
|
|
area += measureArea(poly);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
let maxIndex = Max(areas, (t1, t2) => t2 > t1);
|
|
|
|
|
|
|
|
|
|
newGeom.polygons = polyGroups[maxIndex];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
this._EdgeGeometry = new EdgesGeometry().FromCSG(newGeom as unknown as Geom3Res);
|
|
|
|
|
const geometry = CSG2Geometry2(newGeom);
|
|
|
|
|
|
|
|
|
|
const bufferGeometry = new BufferGeometry().fromGeometry(geometry);
|
|
|
|
|