同步源码

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

@@ -1693,7 +1693,7 @@ exports.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);
}
/**
* 测试两个实体的包围盒是否相交.
@@ -3712,6 +3712,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 three.Plane {
constructor(normal = new three.Vector3(0, 0, 1), constant) {
super(normal);
@@ -4166,7 +4205,7 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.Curve {
return this._startAngle;
}
get EndAngle() {
return this._startAngle;
return this._endAngle;
}
set StartAngle(v) {
this.WriteAllObjectRecord();
@@ -4198,7 +4237,7 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.Curve {
}
get TotalAngle() {
let totolAngle = this._endAngle - this._startAngle;
if (totolAngle < 0)
if (totolAngle <= 0)
totolAngle = Math.PI * 2 + totolAngle;
return totolAngle;
}
@@ -4209,16 +4248,20 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.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);
@@ -4226,28 +4269,31 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.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 three.Vector3(a * Math.cos(an), b * Math.sin(an), 0);
pt.applyMatrix4(new three.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) {
@@ -4264,28 +4310,19 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.Curve {
GetParamAtDist(d) {
return d / this.Length;
}
GetAngleAtParam(par) {
let pt = this.GetPointAtParam(par).applyMatrix4(this.OCSInv).applyMatrix4(new three.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) {
@@ -4308,8 +4345,8 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.Curve {
let k = -(this._radY ** 2 * p.x) / (this._radX ** 2 * p.y);
vec.set(1, k, 0);
}
vec.applyMatrix4(new three.Matrix4().makeRotationZ(this._rotate));
return vec.applyMatrix4(new three.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/
@@ -4337,7 +4374,7 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.Curve {
let dt = dc / Math.sqrt(a * a + b * b - x * x - y * y);
t += dt;
}
let retPt = new three.Vector3(x, y).applyMatrix4(ro).applyMatrix4(this.OCS);
let retPt = new three.Vector3(x, y).applyMatrix4(ro).applyMatrix4(this.OCSNoClone);
if (this.IsClose || extend) {
return retPt;
}
@@ -4464,7 +4501,9 @@ exports.Ellipse = Ellipse_1 = class Ellipse extends exports.Curve {
new three.Vector3(-this._radX, 0),
new three.Vector3(0, this._radY),
new three.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))
@@ -5712,7 +5751,8 @@ const fuzz = 1e-3;
let fuzzV3 = new three.Vector3(fuzz, fuzz, fuzz);
//判断小曲线是不是被大曲线包含(或者重叠?)
function isTargetCurInOrOnSourceCur(bigCurve, smallCurve) {
if (!bigCurve.BoundingBox.expandByVector(fuzzV3).containsBox(smallCurve.BoundingBox))
//#fix fileid 2087494 使用二维的box来计算看起来没有问题
if (!three.Box2.prototype.containsBox.apply(bigCurve.BoundingBox.expandByVector(fuzzV3), [smallCurve.BoundingBox]))
return false;
let cus = [];
if (smallCurve instanceof exports.Polyline)
@@ -6132,7 +6172,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));
@@ -6147,7 +6187,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();
@@ -8651,13 +8691,28 @@ function IntersectPolylineAndCurve(pl, cu, extType, tolerance = 1e-6) {
return intRes;
}
function IntersectLineAndEllipseFor2D(l, el) {
if (!l.IsCoplaneTo(el))
return [];
let mat = new three.Matrix4().makeRotationZ(-el.Rotation).multiply(el.OCSInv);
let elInv = new three.Matrix4().makeRotationZ(-el.Rotation).multiply(el.OCSInv);
let matInv = new three.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;
@@ -8698,7 +8753,6 @@ function IntersectLineAndEllipseFor2D(l, el) {
];
}
}
let matInv = new three.Matrix4().getInverse(mat);
return pts.map(p => {
let pt = p.applyMatrix4(matInv);
return {
@@ -9202,11 +9256,7 @@ exports.Arc = Arc_1 = class Arc extends exports.Curve {
}
/**
* 计算所包含的角度
*
* @private
* @param {number} endAngle 结束的角度
* @returns
* @memberof Arc
*/
ComputeAnlge(endAngle) {
//顺时针
@@ -9496,7 +9546,7 @@ function getDeterminantFor2V(v1, v2) {
* [c1,c2,c3...],
* ]
*/
function curveLinkGroup(cus) {
function curveLinkGroup(cus, numdimensions = 4) {
//返回的曲线组
let groupCus = new Array();
//将封闭的曲线先提取出来
@@ -9508,8 +9558,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;
@@ -9528,13 +9579,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);
}
@@ -16183,11 +16234,9 @@ exports.ExtrudeSolid = ExtrudeSolid_1 = class ExtrudeSolid extends exports.Entit
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) !== exports.Status.True)
return [];
@@ -18804,7 +18853,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,
@@ -21974,45 +22023,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;
@@ -35322,6 +35332,11 @@ exports.ArcDimension = class ArcDimension extends exports.Dimension {
}
return this._Text;
}
get Arc() {
if (!this._Arc)
this.PraseArc();
return this._Arc;
}
set TextRadiusAdd(ra) {
if (equaln(ra, this._TextRadiusAdd))
return;