mirror of https://gitee.com/cf-fz/WebCAD.git
!1804 重构:新的板件交集算法,影响:板件干涉,板件切割(非平行垂直时)
parent
9485fa687c
commit
60d3738cc7
@ -0,0 +1,33 @@
|
|||||||
|
import { Geom3 } from "@jscad/modeling/src/geometries/types";
|
||||||
|
import { Mat4 } from "@jscad/modeling/src/maths/mat4";
|
||||||
|
import { Vec3 } from "@jscad/modeling/src/maths/vec3";
|
||||||
|
import { intersect } from "@jscad/modeling/src/operations/booleans";
|
||||||
|
import { Matrix4 } from "three";
|
||||||
|
|
||||||
|
export interface Geom3Res
|
||||||
|
{
|
||||||
|
polygons: Array<{
|
||||||
|
vertices: Array<Vec3>,
|
||||||
|
plane: [number, number, number, number];
|
||||||
|
}>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function CSGIntersect(csg1: Geom3, csg2: Geom3, csg2tranfrom: Matrix4): Geom3Res
|
||||||
|
{
|
||||||
|
let bak1 = csg1.polygons;
|
||||||
|
let bak2 = csg2.polygons;
|
||||||
|
|
||||||
|
let bakMtx = csg2.transforms;
|
||||||
|
|
||||||
|
csg2.transforms = csg2tranfrom.elements as Mat4;
|
||||||
|
|
||||||
|
csg1.polygons = bak1.concat();
|
||||||
|
csg2.polygons = bak2.concat();
|
||||||
|
|
||||||
|
let res = intersect(csg1, csg2) as unknown as Geom3Res;
|
||||||
|
|
||||||
|
csg1.polygons = bak1;
|
||||||
|
csg2.polygons = bak2;
|
||||||
|
csg2.transforms = bakMtx;
|
||||||
|
return res;
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
import { geom2 } from "@jscad/modeling/src/geometries";
|
||||||
|
import { Geom3 } from "@jscad/modeling/src/geometries/geom3/";
|
||||||
|
import { Mat4 } from "@jscad/modeling/src/maths/mat4";
|
||||||
|
import { subtract } from "@jscad/modeling/src/operations/booleans";
|
||||||
|
import { extrudeLinear } from "@jscad/modeling/src/operations/extrusions";
|
||||||
|
import { ExtrudeSolid } from "../../DatabaseServices/Entity/Extrude";
|
||||||
|
import { SplitCurveParams } from "./SplitCurveParams";
|
||||||
|
|
||||||
|
//使用这个算法会有性能问题 用webworker会好一点,不到必要时刻不使用(例如切斜边 和 二维刀路造型)
|
||||||
|
export function ExtBuildCSG(ext: ExtrudeSolid): Geom3
|
||||||
|
{
|
||||||
|
let c = ext.ContourCurve;
|
||||||
|
let pts = SplitCurveParams(c).map(p => c.GetPointAtParam(p));
|
||||||
|
let geo2 = geom2.fromPoints(pts.map(p => [p.x, p.y]));
|
||||||
|
let geo = extrudeLinear({ height: ext.Thickness }, geo2);
|
||||||
|
|
||||||
|
let grooveGeo: Geom3[] = ext.Grooves.map(ExtBuildCSG);
|
||||||
|
|
||||||
|
geo.transforms = ext.OCSNoClone.elements as Mat4;
|
||||||
|
|
||||||
|
if (grooveGeo.length)
|
||||||
|
return subtract(geo, grooveGeo);
|
||||||
|
else
|
||||||
|
return geo;
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
import { arraySortByNumber } from "../../Common/ArrayExt";
|
||||||
|
import { clamp } from "../../Common/Utils";
|
||||||
|
import { Arc } from "../../DatabaseServices/Entity/Arc";
|
||||||
|
import { Circle } from "../../DatabaseServices/Entity/Circle";
|
||||||
|
import { ExtureContourCurve } from "../../DatabaseServices/Entity/Extrude";
|
||||||
|
|
||||||
|
const ARC_SplitLength = 4;//圆的分段长度
|
||||||
|
const Arc_MinSplitCount = 12;//圆的最小分段个数
|
||||||
|
const ARC_MaxSplitCount = 360;//圆的最大分段个数
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param cu
|
||||||
|
* @returns
|
||||||
|
*/
|
||||||
|
export function SplitCurveParams(cu: ExtureContourCurve): number[]
|
||||||
|
{
|
||||||
|
let xparams: number[] = [];
|
||||||
|
if (cu instanceof Circle)
|
||||||
|
{
|
||||||
|
let splitCount = cu.Radius / ARC_SplitLength;
|
||||||
|
splitCount = clamp(Math.floor(splitCount), Arc_MinSplitCount, ARC_MaxSplitCount);
|
||||||
|
for (let i = 0; i < splitCount; i++)
|
||||||
|
xparams.push(i / splitCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
else
|
||||||
|
//分段1
|
||||||
|
for (let i = 0; i < cu.EndParam; i++)
|
||||||
|
{
|
||||||
|
xparams.push(i);
|
||||||
|
if (cu.GetBuilgeAt(i) !== 0)
|
||||||
|
{
|
||||||
|
let arc = cu.GetCurveAtIndex(i) as Arc;
|
||||||
|
let splitCount = arc.Radius / ARC_SplitLength;
|
||||||
|
splitCount = clamp(Math.floor(splitCount), Arc_MinSplitCount, ARC_MaxSplitCount);
|
||||||
|
if (splitCount === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
let a = Math.PI * 2 / splitCount;
|
||||||
|
let params: number[] = [];
|
||||||
|
for (let j = 0; j < splitCount; j++)
|
||||||
|
{
|
||||||
|
let param = arc.GetParamAtAngle(a * j);
|
||||||
|
if (arc.ParamOnCurve(param))
|
||||||
|
params.push(param);
|
||||||
|
}
|
||||||
|
arraySortByNumber(params);
|
||||||
|
if (params.length === 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (let p of params)
|
||||||
|
{
|
||||||
|
if (p > 1e-5 && p < 9.99999)
|
||||||
|
xparams.push(p + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
xparams.push(cu.EndParam);
|
||||||
|
return xparams;
|
||||||
|
}
|
@ -1,34 +1,37 @@
|
|||||||
import { BufferGeometry, Vector3 } from "three";
|
import { BufferGeometry, Vector3 } from "three";
|
||||||
import { arrayLast, arrayPushArray } from "../Common/ArrayExt";
|
import { arrayLast, arrayPushArray } from "../Common/ArrayExt";
|
||||||
import { FixIndex } from "../Common/Utils";
|
import { FixIndex } from "../Common/Utils";
|
||||||
import { equalv3 } from "./GeUtils";
|
import { equalv3 } from "./GeUtils";
|
||||||
|
|
||||||
export function GenerateExtrudeEdgeGeometry(contourPoints: Vector3[][], height: number): BufferGeometry
|
//使用轮廓点表快速拉伸
|
||||||
{
|
export function GenerateExtrudeEdgeGeometry(contourPoints: Vector3[][], height: number): BufferGeometry
|
||||||
let pts: Vector3[] = [];
|
{
|
||||||
for (let cs of contourPoints)
|
let pts: Vector3[] = [];
|
||||||
arrayPushArray(pts, GenerateExtrudeEdgeGeometryPoints(cs, height));
|
for (let cs of contourPoints)
|
||||||
let geo = new BufferGeometry().setFromPoints(pts);
|
arrayPushArray(pts, GenerateExtrudeEdgeGeometryPoints(cs, height));
|
||||||
return geo;
|
let geo = new BufferGeometry().setFromPoints(pts);
|
||||||
}
|
return geo;
|
||||||
|
}
|
||||||
function GenerateExtrudeEdgeGeometryPoints(contourPoints: Vector3[], height: number): Vector3[]
|
|
||||||
{
|
//拉伸点表成为Geom
|
||||||
if (contourPoints.length < 3) return [];
|
function GenerateExtrudeEdgeGeometryPoints(contourPoints: Vector3[], height: number): Vector3[]
|
||||||
if (equalv3(contourPoints[0], arrayLast(contourPoints)))
|
{
|
||||||
contourPoints.pop();
|
if (contourPoints.length < 3) return [];
|
||||||
let pts: Vector3[] = [];
|
if (equalv3(contourPoints[0], arrayLast(contourPoints)))
|
||||||
let hpts = contourPoints.map(p => new Vector3(p.x, p.y, height));
|
contourPoints.pop();
|
||||||
let count = contourPoints.length;
|
let pts: Vector3[] = [];
|
||||||
for (let i = 0; i < count; i++)
|
let hpts = contourPoints.map(p => new Vector3(p.x, p.y, height));
|
||||||
{
|
let count = contourPoints.length;
|
||||||
pts.push(contourPoints[i], contourPoints[FixIndex(i + 1, count)], hpts[i], hpts[FixIndex(i + 1, count)], contourPoints[i], hpts[i]);
|
for (let i = 0; i < count; i++)
|
||||||
}
|
{
|
||||||
return pts;
|
pts.push(contourPoints[i], contourPoints[FixIndex(i + 1, count)], hpts[i], hpts[FixIndex(i + 1, count)], contourPoints[i], hpts[i]);
|
||||||
}
|
}
|
||||||
|
return pts;
|
||||||
export function GenerateBoxEdgeGeometry(length: number, width: number, height: number): BufferGeometry
|
}
|
||||||
{
|
|
||||||
let pts = [new Vector3(), new Vector3(length), new Vector3(length, width), new Vector3(0, width)];
|
//创建一个盒子几何体
|
||||||
return GenerateExtrudeEdgeGeometry([pts], height);
|
export function GenerateBoxEdgeGeometry(length: number, width: number, height: number): BufferGeometry
|
||||||
}
|
{
|
||||||
|
let pts = [new Vector3(), new Vector3(length), new Vector3(length, width), new Vector3(0, width)];
|
||||||
|
return GenerateExtrudeEdgeGeometry([pts], height);
|
||||||
|
}
|
Loading…
Reference in new issue