同步源码

This commit is contained in:
ChenX
2023-04-20 15:08:17 +08:00
parent 6ce49f3885
commit 72cd78190b
61 changed files with 351 additions and 404 deletions

View File

@@ -1,4 +1,4 @@
import { Vector3, Matrix4, Box3, Color, FrontSide, MeshPhysicalMaterial, Object3D, Vector2 as Vector2$1, Quaternion, MathUtils, Shape as Shape$1, EllipseCurve, LineDashedMaterial, DoubleSide, MeshBasicMaterial, LineBasicMaterial, ShaderMaterial, BufferGeometry, ShapeGeometry, BufferAttribute, Line as Line$1, Plane, Line3, CatmullRomCurve3, Path as Path$1, LineSegments, Mesh, CylinderBufferGeometry, Float32BufferAttribute, Geometry, ShapeUtils, Face3, BoxBufferGeometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, ExtrudeGeometry, BoxGeometry, Euler, OrthographicCamera, PerspectiveCamera, AmbientLight as AmbientLight$1, DirectionalLightHelper, SphereBufferGeometry, Matrix3, Group, DirectionalLight as DirectionalLight$1, HemisphereLight as HemisphereLight$1, MirroredRepeatWrapping, Texture, Scene, WebGLRenderTarget, Frustum, MeshNormalMaterial, PointLight as PointLight$1, SphereGeometry, BackSide, RectAreaLight as RectAreaLight$1, SpotLight as SpotLight$1, ConeGeometry, PointsMaterial, Points, Box2 as Box2$1, Raycaster } from 'three';
import { Vector3, Matrix4, Box3, Color, FrontSide, MeshPhysicalMaterial, Object3D, Vector2 as Vector2$1, Quaternion, MathUtils, Shape as Shape$1, EllipseCurve, LineDashedMaterial, DoubleSide, MeshBasicMaterial, LineBasicMaterial, ShaderMaterial, BufferGeometry, ShapeGeometry, BufferAttribute, Line as Line$1, Plane, Line3, CatmullRomCurve3, Box2 as Box2$1, Path as Path$1, LineSegments, Mesh, CylinderBufferGeometry, Float32BufferAttribute, Geometry, ShapeUtils, Face3, BoxBufferGeometry, InstancedInterleavedBuffer, InterleavedBufferAttribute, ExtrudeGeometry, BoxGeometry, Euler, OrthographicCamera, PerspectiveCamera, AmbientLight as AmbientLight$1, DirectionalLightHelper, SphereBufferGeometry, Matrix3, Group, DirectionalLight as DirectionalLight$1, HemisphereLight as HemisphereLight$1, MirroredRepeatWrapping, Texture, Scene, WebGLRenderTarget, Frustum, MeshNormalMaterial, PointLight as PointLight$1, SphereGeometry, BackSide, RectAreaLight as RectAreaLight$1, SpotLight as SpotLight$1, ConeGeometry, PointsMaterial, Points, Raycaster } from 'three';
import { iaop, end } from 'xaop';
import { Line2 } from 'three/examples/jsm/lines/Line2';
import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry';
@@ -1664,7 +1664,7 @@ let Entity = Entity_1 = class Entity extends CADObject {
* 与指定实体是否共面.
*/
IsCoplaneTo(e) {
return matrixIsCoplane(this._Matrix, e.OCS, 1e-4);
return matrixIsCoplane(this._Matrix, e.OCSNoClone, 1e-4);
}
/**
* 测试两个实体的包围盒是否相交.
@@ -3683,6 +3683,45 @@ var DragPointType;
DragPointType[DragPointType["Stretch"] = 1] = "Stretch";
})(DragPointType || (DragPointType = {}));
class Matrix2 {
constructor() {
//column-major
this.el = [1, 0, 0, 1]; //ix iy jx jy [a c b d]
}
set(ix, iy, jx, jy) {
this.el[0] = ix;
this.el[1] = iy;
this.el[2] = jx;
this.el[3] = jy;
return this;
}
applyVector(vec) {
let x = vec.x;
let y = vec.y;
let e = this.el;
vec.x = e[0] * x + e[2] * y;
vec.y = e[1] * x + e[3] * y;
return this;
}
fromMatrix4(mtx4) {
this.set(mtx4.elements[0], mtx4.elements[1], mtx4.elements[3], mtx4.elements[4]);
}
setRotate(theta) {
let c = Math.cos(theta);
let s = Math.sin(theta);
this.set(c, s, -s, c);
return this;
}
//自我求逆矩阵,返回自身
invert() {
//ref:https://www.mathsisfun.com/algebra/matrix-inverse.html
let [a, c, b, d] = this.el;
let det = 1 / (a * d - b * c);
this.set(d * det, -c * det, -b * det, a * det);
return this;
}
}
class PlaneExt extends Plane {
constructor(normal = new Vector3(0, 0, 1), constant) {
super(normal);
@@ -4137,7 +4176,7 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
return this._startAngle;
}
get EndAngle() {
return this._startAngle;
return this._endAngle;
}
set StartAngle(v) {
this.WriteAllObjectRecord();
@@ -4169,7 +4208,7 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
}
get TotalAngle() {
let totolAngle = this._endAngle - this._startAngle;
if (totolAngle < 0)
if (totolAngle <= 0)
totolAngle = Math.PI * 2 + totolAngle;
return totolAngle;
}
@@ -4180,16 +4219,20 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
this.Position = p;
return this;
}
Extend(newParam) {
this.WriteAllObjectRecord();
if (newParam < 0)
this._startAngle = this.GetAngleAtParam(newParam);
else if (newParam > 1)
this._endAngle = this.GetAngleAtParam(newParam);
this.Update();
}
PtInCurve(pt) {
let p = rotatePoint(pt.clone().sub(this.Center), -this.Rotation);
return p.x ** 2 / this.RadX ** 2 + p.y ** 2 / this.RadY ** 2 < 1;
}
PtOnCurve(pt) {
if (this.PtOnEllipse(pt)) {
let a = this.GetCircleAngleAtPoint(pt);
return a <= this.TotalAngle + 1e-6;
}
return false;
return this.PtOnEllipse(pt) && this.ParamOnCurve(this.GetParamAtPoint(pt));
}
PtOnEllipse(pt) {
let p = rotatePoint(pt.clone().applyMatrix4(this.OCSInv), -this.Rotation);
@@ -4197,28 +4240,31 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
}
GetPointAtParam(param) {
let an = this.TotalAngle * param + this._startAngle;
if (an > Math.PI)
an -= 2 * Math.PI;
let a = this.RadX;
let b = this.RadY;
let pt = new Vector3(a * Math.cos(an), b * Math.sin(an), 0);
pt.applyMatrix4(new Matrix4().makeRotationZ(this._rotate));
return pt.applyMatrix4(this.OCS);
let mtx = new Matrix2().setRotate(this._rotate);
mtx.applyVector(pt);
return pt.applyMatrix4(this.OCSNoClone);
}
GetParamAtPoint(pt) {
if (!this.PtOnEllipse(pt)) {
if (!this.PtOnEllipse(pt))
return NaN;
}
let an = this.GetCircleAngleAtPoint(pt);
let par = an / this.TotalAngle;
if (this.IsClose || par < 1 + 1e-6)
return par;
let allAngle = this.TotalAngle;
let param = an / allAngle;
if (this.IsClose)
return param;
else {
let diffPar = Math.PI * 2 / this.TotalAngle - 1;
if (par - 1 < diffPar / 2)
return par;
if (an >= this._startAngle)
param = (an - this._startAngle) / allAngle;
else
return par - 1 - diffPar;
param = ((Math.PI * 2) - (this._startAngle - an)) / allAngle;
//剩余的参数
let remParam = Math.PI * 2 / allAngle - 1;
if (param > (remParam * 0.5 + 1)) //一半
param = (param - 1) - remParam; //返回负数
return param;
}
}
GetPointAtDistance(distance) {
@@ -4235,28 +4281,19 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
GetParamAtDist(d) {
return d / this.Length;
}
GetAngleAtParam(par) {
let pt = this.GetPointAtParam(par).applyMatrix4(this.OCSInv).applyMatrix4(new Matrix4().makeRotationZ(-this.Rotation));
return angle(pt) + this._startAngle;
GetAngleAtParam(param) {
return this._startAngle + param * this.TotalAngle;
}
GetCircleAngleAtPoint(pt) {
pt = pt.clone().applyMatrix4(this.OCSInv);
let an = angle(pt) - this._rotate;
if (an < 0)
an = Math.PI * 2 - an;
if (an > Math.PI * 2)
an -= Math.PI * 2;
let dist = pt.length();
let k = dist * Math.cos(an) / this._radX;
if (Math.abs(k) > 1)
k = Math.floor(Math.abs(k)) * Math.sign(k);
if (Math.abs(an) <= Math.PI)
an = Math.acos(k);
else
an = Math.PI * 2 - Math.acos(k);
an -= this._startAngle;
if (an < 0)
an = Math.PI * 2 + an;
let romtx = new Matrix2().setRotate(-this._rotate);
romtx.applyVector(pt);
//https://www.petercollingridge.co.uk/tutorials/computational-geometry/finding-angle-around-ellipse/
let an = Math.atan(this.RadX * pt.y / (this.RadY * pt.x));
if (pt.x < 0)
an += Math.PI;
else if (an < 0)
an += Math.PI * 2;
return an;
}
GetFistDeriv(pt) {
@@ -4279,8 +4316,8 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
let k = -(this._radY ** 2 * p.x) / (this._radX ** 2 * p.y);
vec.set(1, k, 0);
}
vec.applyMatrix4(new Matrix4().makeRotationZ(this._rotate));
return vec.applyMatrix4(new Matrix4().extractRotation(this.OCS));
rotatePoint(vec, this._rotate);
return vec.applyMatrix4(this.OCS.setPosition(0, 0, 0));
}
GetClosestPointTo(p, extend) {
//参考:https://wet-robots.ghost.io/simple-method-for-distance-to-ellipse/
@@ -4308,7 +4345,7 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
let dt = dc / Math.sqrt(a * a + b * b - x * x - y * y);
t += dt;
}
let retPt = new Vector3(x, y).applyMatrix4(ro).applyMatrix4(this.OCS);
let retPt = new Vector3(x, y).applyMatrix4(ro).applyMatrix4(this.OCSNoClone);
if (this.IsClose || extend) {
return retPt;
}
@@ -4435,7 +4472,9 @@ let Ellipse = Ellipse_1 = class Ellipse extends Curve {
new Vector3(-this._radX, 0),
new Vector3(0, this._radY),
new Vector3(0, -this._radY)
].map(p => p.applyMatrix4(tmpMat4).applyMatrix4(this.OCS));
];
for (let p of pts)
p.applyMatrix4(tmpMat4).applyMatrix4(this.OCSNoClone);
if (!equaln$1(0, this._startAngle))
pts.push(this.StartPoint);
if (!equaln$1(0, this._endAngle))
@@ -5683,7 +5722,8 @@ const fuzz = 1e-3;
let fuzzV3 = new Vector3(fuzz, fuzz, fuzz);
//判断小曲线是不是被大曲线包含(或者重叠?)
function isTargetCurInOrOnSourceCur(bigCurve, smallCurve) {
if (!bigCurve.BoundingBox.expandByVector(fuzzV3).containsBox(smallCurve.BoundingBox))
//#fix fileid 2087494 使用二维的box来计算看起来没有问题
if (!Box2$1.prototype.containsBox.apply(bigCurve.BoundingBox.expandByVector(fuzzV3), [smallCurve.BoundingBox]))
return false;
let cus = [];
if (smallCurve instanceof Polyline)
@@ -6103,7 +6143,7 @@ class Contour {
if (Array.isArray(cus[0]))
cuGroups = cus;
else
cuGroups = curveLinkGroup(cus);
cuGroups = curveLinkGroup(cus, -Math.log10(COMBINE_FUZZ));
let contours = [];
for (let g of cuGroups)
contours.push(Contour.CreateContour(g, false));
@@ -6118,7 +6158,7 @@ class Contour {
static Combine(cus, needLink = true, tolerance = 1e-3) {
if (cus.length === 0)
return undefined;
let groups = needLink ? curveLinkGroup(cus) : [cus];
let groups = needLink ? curveLinkGroup(cus, -Math.log10(tolerance)) : [cus];
for (let g of groups) {
if (g.length === 1)
return g[0].Clone();
@@ -8622,13 +8662,28 @@ function IntersectPolylineAndCurve(pl, cu, extType, tolerance = 1e-6) {
return intRes;
}
function IntersectLineAndEllipseFor2D(l, el) {
if (!l.IsCoplaneTo(el))
return [];
let mat = new Matrix4().makeRotationZ(-el.Rotation).multiply(el.OCSInv);
let elInv = new Matrix4().makeRotationZ(-el.Rotation).multiply(el.OCSInv);
let matInv = new Matrix4().getInverse(elInv);
let a = el.RadX;
let b = el.RadY;
let sp = l.StartPoint.applyMatrix4(mat);
let ep = l.EndPoint.applyMatrix4(mat);
let sp = l.StartPoint.applyMatrix4(elInv);
let ep = l.EndPoint.applyMatrix4(elInv);
if (!(equaln$1(sp.z, 1e-6) && equaln$1(ep.z, 1e-6))) {
if (equalv2(sp, ep, 1e-6)) //如果与之垂直
{
let p = sp.setZ(0).applyMatrix4(matInv);
if (el.PtOnCurve(p))
return [
{
pt: p,
thisParam: l.GetParamAtPoint(p),
argParam: el.GetParamAtPoint(p)
}
];
}
//todo:求交面
return [];
}
let pts = [];
if (equaln$1(sp.x, ep.x)) {
let c = sp.x;
@@ -8669,7 +8724,6 @@ function IntersectLineAndEllipseFor2D(l, el) {
];
}
}
let matInv = new Matrix4().getInverse(mat);
return pts.map(p => {
let pt = p.applyMatrix4(matInv);
return {
@@ -9173,11 +9227,7 @@ let Arc = Arc_1 = class Arc extends Curve {
}
/**
* 计算所包含的角度
*
* @private
* @param {number} endAngle 结束的角度
* @returns
* @memberof Arc
*/
ComputeAnlge(endAngle) {
//顺时针
@@ -9467,7 +9517,7 @@ function getDeterminantFor2V(v1, v2) {
* [c1,c2,c3...],
* ]
*/
function curveLinkGroup(cus) {
function curveLinkGroup(cus, numdimensions = 4) {
//返回的曲线组
let groupCus = new Array();
//将封闭的曲线先提取出来
@@ -9479,8 +9529,9 @@ function curveLinkGroup(cus) {
});
if (cus.length === 0)
return groupCus;
const fuzz = 5 * Math.pow(0.1, numdimensions);
//曲线节点图
let cuMap = new CurveMap();
let cuMap = new CurveMap(numdimensions);
cus.forEach(c => cuMap.AddCurveToMap(c));
//曲线站点表
let stands = cuMap.Stands;
@@ -9499,13 +9550,13 @@ function curveLinkGroup(cus) {
if (cuCount.GetCount(cu) === 0) {
if (isEndSeach) {
//保证曲线总是从起点连接到终点
if (!equalv3(cu.StartPoint, stand.position))
if (!equalv3(cu.StartPoint, stand.position, fuzz))
cu.Reverse();
cus.push(cu);
}
else {
//保证曲线总是从起点连接到终点
if (!equalv3(cu.EndPoint, stand.position))
if (!equalv3(cu.EndPoint, stand.position, fuzz))
cu.Reverse();
cus.unshift(cu);
}
@@ -16154,11 +16205,9 @@ let ExtrudeSolid = ExtrudeSolid_1 = class ExtrudeSolid extends Entity {
if (parType > 0) {
target = target.Clone().ClearDraw();
if (parType === 2) {
let mtx = target._Matrix;
SetMtxVector(mtx, 2, n1);
let p = n1.setFromMatrixColumn(mtx, 3);
p.add(n2.multiplyScalar(target.thickness));
SetMtxVector(mtx, 3, p);
let p = target.Position;
p.add(n2.clone().multiplyScalar(target.thickness * 0.5));
target.ApplyMatrix(MakeMirrorMtx(n2, p));
}
if (this.GrooveCheckPosition(target) !== Status.True)
return [];
@@ -18775,7 +18824,7 @@ function GetModelingFromCustomDrill(br) {
}
else
continue;
if (thickness > +1e-6 && isTargetCurInOrOnSourceCur(outline, shape.Outline.Curve.Clone().Z0())) {
if (thickness > 1e-6 && isTargetCurInOrOnSourceCur(outline, shape.Outline.Curve.Clone().Z0())) {
modeling.push({
shape,
thickness,
@@ -21945,45 +21994,6 @@ class CurveTrimArc extends CurveTrim {
}
}
class Matrix2 {
constructor() {
//column-major
this.el = [1, 0, 0, 1]; //ix iy jx jy [a c b d]
}
set(ix, iy, jx, jy) {
this.el[0] = ix;
this.el[1] = iy;
this.el[2] = jx;
this.el[3] = jy;
return this;
}
applyVector(vec) {
let x = vec.x;
let y = vec.y;
let e = this.el;
vec.x = e[0] * x + e[2] * y;
vec.y = e[1] * x + e[3] * y;
return this;
}
fromMatrix4(mtx4) {
this.set(mtx4.elements[0], mtx4.elements[1], mtx4.elements[3], mtx4.elements[4]);
}
setRotate(theta) {
let c = Math.cos(theta);
let s = Math.sin(theta);
this.set(c, s, -s, c);
return this;
}
//自我求逆矩阵,返回自身
invert() {
//ref:https://www.mathsisfun.com/algebra/matrix-inverse.html
let [a, c, b, d] = this.el;
let det = 1 / (a * d - b * c);
this.set(d * det, -c * det, -b * det, a * det);
return this;
}
}
function EntityUpdateWrap(ent, exec) {
let oldAutoUpdate = ent.AutoUpdate;
ent.AutoUpdate = false;
@@ -35293,6 +35303,11 @@ let ArcDimension = class ArcDimension extends Dimension {
}
return this._Text;
}
get Arc() {
if (!this._Arc)
this.PraseArc();
return this._Arc;
}
set TextRadiusAdd(ra) {
if (equaln(ra, this._TextRadiusAdd))
return;