功能:序列化相机的FOV

This commit is contained in:
ChenX
2022-09-28 17:26:49 +08:00
parent fd466aadc0
commit 35f2e8fea9
98 changed files with 483 additions and 289 deletions

View File

@@ -1569,8 +1569,14 @@ exports.Entity = Entity_1 = class Entity extends CADObject {
get BoundingBoxInOCS() {
let mtxBak = this._Matrix;
this._Matrix = IdentityMtx4;
let isClearDraw = this._CacheDrawObject.size === 0;
let box = this.BoundingBox;
this._Matrix = mtxBak;
if (isClearDraw) {
for (let [, obj] of this._CacheDrawObject)
obj.matrix = this._Matrix; //因为使用了备份的矩阵,导致此时这个矩形是错误的,这里还原它
this.Update(exports.UpdateDraw.Matrix); //保证盒子是正确的
}
return new Box3Ext().copy(box);
}
GetBoundingBoxInMtx(mtx) {
@@ -2395,9 +2401,10 @@ const comparePointCache = new Map();
* @param {string} sortKey
* @returns {compareVectorFn}
*/
function ComparePointFnGenerate(sortKey) {
if (comparePointCache.has(sortKey))
return comparePointCache.get(sortKey);
function ComparePointFnGenerate(sortKey, fuzz = 1e-8) {
let cacheKey = `${sortKey}${fuzz}`;
if (comparePointCache.has(cacheKey))
return comparePointCache.get(cacheKey);
let sortIndex = [];
const keys = ['x', 'X', 'y', 'Y', 'z', 'Z'];
for (let char of sortKey) {
@@ -2414,7 +2421,7 @@ function ComparePointFnGenerate(sortKey) {
for (let s of sortIndex) {
let vv1 = v1.getComponent(s[0]);
let vv2 = v2.getComponent(s[0]);
if (equaln$1(vv1, vv2))
if (equaln$1(vv1, vv2, fuzz))
continue;
if (vv2 > vv1)
return s[1];
@@ -5997,7 +6004,7 @@ class Contour {
let subtractList = [];
let holes = [];
let intPars = [];
let cuMap = new Map();
let curveIntParamsMap = new Map();
let outBox = sourceOutline.BoundingBox;
for (let con of targets) {
const targetOutline = con.Curve;
@@ -6014,43 +6021,40 @@ class Contour {
}
else {
intPars.push(...pts.map(r => r.thisParam));
cuMap.set(targetOutline, pts.map(r => r.argParam));
curveIntParamsMap.set(targetOutline, pts.map(r => r.argParam));
}
}
intPars.sort((a, b) => a - b);
arrayRemoveDuplicateBySort(intPars, (e1, e2) => equaln$1(e1, e2, 1e-8));
let sourceCus = sourceOutline.GetSplitCurves(intPars);
let targetCus = [];
let targetMap = new WeakMap();
let isEqualNormal;
for (let [c, pars] of cuMap) {
let cus = c.GetSplitCurves(pars);
cus.forEach(cu => targetMap.set(cu, c));
targetCus.push(...cus);
let sourceSplitCurves = sourceOutline.GetSplitCurves(intPars);
let targetSplitCurves = [];
let targetSplitCurve_CurvesMap = new WeakMap(); //分裂后->原始曲线 映射
for (let [curve, intParams] of curveIntParamsMap) {
let splitCurves = curve.GetSplitCurves(intParams);
for (let splitCurve of splitCurves) {
targetSplitCurve_CurvesMap.set(splitCurve, curve);
targetSplitCurves.push(splitCurve);
}
}
for (let pl of sourceCus) {
let plMidParam = pl.MidParam;
let plDir = pl.GetFistDeriv(plMidParam).normalize();
let index = targetCus.findIndex(cu => fastEqualCurve(cu, pl, 0.05));
for (let sourceSplitcu of sourceSplitCurves) {
let sourceDir = sourceSplitcu.GetFistDeriv(sourceSplitcu.MidParam).normalize();
let index = targetSplitCurves.findIndex(cu => fastEqualCurve(cu, sourceSplitcu, 0.05));
if (index !== -1) {
let cu = targetCus[index];
isEqualNormal = equalv3(sourceOutline.Normal, targetMap.get(cu).Normal, 1e-3);
let cuMidParam = cu.MidParam;
let cuDir = cu.GetFistDeriv(cuMidParam).normalize();
if (isEqualNormal === !equalv3(cuDir, plDir, 1e-3)) //不同向
subtractList.push(pl);
targetCus.splice(index, 1);
let targetSplitcu = targetSplitCurves[index];
let isEqualNormal = equalv3(sourceOutline.Normal, targetSplitCurve_CurvesMap.get(targetSplitcu).Normal, 1e-3);
let targetDir = targetSplitcu.GetFistDeriv(targetSplitcu.MidParam).normalize();
if (isEqualNormal === !equalv3(targetDir, sourceDir, 1e-3)) //不同向
subtractList.push(sourceSplitcu);
targetSplitCurves.splice(index, 1);
continue;
}
if (targets.every(t => !fastCurveInCurve(t.Curve, pl)))
subtractList.push(pl);
if (targets.every(t => !fastCurveInCurve(t.Curve, sourceSplitcu)))
subtractList.push(sourceSplitcu);
}
//源对象没有被破坏
let sourceNotBreak = subtractList.length === sourceCus.length;
for (let pl of targetCus)
let sourceNotBreak = subtractList.length === sourceSplitCurves.length;
for (let pl of targetSplitCurves)
if (fastCurveInCurve(sourceOutline, pl))
subtractList.push(pl);
if (sourceNotBreak && subtractList.length === sourceCus.length)
if (sourceNotBreak && subtractList.length === sourceSplitCurves.length)
return { subtractList: [sourceOutline], holes };
return { subtractList, holes };
}
@@ -6761,7 +6765,7 @@ function IsPointInPolyLine(pl, pt) {
let crossings = 0;
let insLine = new exports.Line(pt, pt.clone().add(new three.Vector3(0, 10, 0)));
for (let i = 0; i < pl.EndParam; i++) {
if (equaln$1(pl.GetBulgeAt(i), 0, 5e-6)) //直线
if (equaln$1(pl.GetBulgeAt(i), 0, BUL_IS_LINE_FUZZ)) //直线
{
let sp = pl.GetPointAtParam(i);
let ep = pl.GetPointAtParam(i + 1);
@@ -6834,6 +6838,7 @@ function IsPointInPolyLine(pl, pt) {
}
var Polyline_1;
const BUL_IS_LINE_FUZZ = 1e-5;
exports.Polyline = Polyline_1 = class Polyline extends exports.Curve {
constructor(_LineData = []) {
super();
@@ -7814,7 +7819,7 @@ exports.Polyline = Polyline_1 = class Polyline extends exports.Curve {
let d1 = this._LineData[i];
let d2 = this._LineData[FixIndex$1(i + 1, this._LineData)];
let curve;
if (equaln$1(d1.bul, 0, 1e-5))
if (equaln$1(d1.bul, 0, BUL_IS_LINE_FUZZ))
curve = new exports.Line(AsVector3(d1.pt), AsVector3(d2.pt)).ApplyMatrix(this.OCSNoClone);
else
curve = new exports.Arc().ParseFromBul(d1.pt, d2.pt, d1.bul).ApplyMatrix(this.OCSNoClone);
@@ -8536,6 +8541,9 @@ function IntersectPolylineAndCurve(pl, cu, extType, tolerance = 1e-6) {
}));
}
}
let fn = ComparePointFnGenerate("xyz", tolerance);
intRes.sort((p1, p2) => fn(p1.pt, p2.pt));
arrayRemoveDuplicateBySort(intRes, (p1, p2) => equalv2(p1.pt, p2.pt, tolerance));
return intRes;
}
function IntersectLineAndEllipseFor2D(l, el) {
@@ -11362,7 +11370,7 @@ const TempRectHoleOption = {
right: "",
};
/**分析上下左右排钻 */
function InitRectBoardHoleOption(br, option) {
function ParseBoardRectHoleType(br, outBrRectHoleType = {}) {
let dir = Math.sign(br.ContourCurve.Area2);
let hightDrill = br.BoardProcessOption.highDrill;
let cus = br.ContourCurve.Explode();
@@ -11371,17 +11379,18 @@ function InitRectBoardHoleOption(br, option) {
let derv = c.GetFistDeriv(0).multiplyScalar(dir);
if (Math.abs(derv.x) > Math.abs(derv.y)) {
if (derv.x > 0)
option.down = hightDrill[i];
outBrRectHoleType.down = hightDrill[i];
else
option.up = hightDrill[i];
outBrRectHoleType.up = hightDrill[i];
}
else {
if (derv.y > 0)
option.right = hightDrill[i];
outBrRectHoleType.right = hightDrill[i];
else
option.left = hightDrill[i];
outBrRectHoleType.left = hightDrill[i];
}
}
return outBrRectHoleType;
}
function ExtureHoleInBoard(holes, board, ocs) {
//TODO:自定义排钻判断
@@ -11397,8 +11406,8 @@ function HoleInBoard(holes, br, ocs) {
return ExtureHoleInBoard(holes, br, ocs ?? br.OCSInv);
}
}
/**上下左右排钻写入板件 */
function SetRectHighHole(br, option) {
/**上下左右排钻写入板件的高级排钻中 */
function SetBrHighHoleTypeFromRectHoleType(br, brRectHoleType) {
let dir = Math.sign(br.ContourCurve.Area2);
let highDrill = br.BoardProcessOption.highDrill;
let cus = br.ContourCurve.Explode();
@@ -11408,15 +11417,15 @@ function SetRectHighHole(br, option) {
let derv = c.GetFistDeriv(0).multiplyScalar(dir);
if (Math.abs(derv.x) > Math.abs(derv.y)) {
if (derv.x > 0)
highDrill.push(option.down);
highDrill.push(brRectHoleType.down);
else
highDrill.push(option.up);
highDrill.push(brRectHoleType.up);
}
else {
if (derv.y > 0)
highDrill.push(option.right);
highDrill.push(brRectHoleType.right);
else
highDrill.push(option.left);
highDrill.push(brRectHoleType.left);
}
}
let types = new Set(highDrill);
@@ -18847,6 +18856,8 @@ var Production;
//避免共线导致的侧面数据对应错误
let cus = con.Explode();
MergeCurvelist(cus);
if (cus.length === 1 && cus[0] instanceof exports.Circle)
return cus[0];
let pl = exports.Polyline.FastCombine(cus, LINK_FUZZ);
if (pl && isSplite && pl.Area2 < 0)
pl.Reverse();
@@ -20121,13 +20132,14 @@ exports.Board = Board_1 = class Board extends exports.ExtrudeSolid {
}
get SplitBoards() {
let brs = this.SplitExtrudes;
let dridatas;
let highDrills;
let ocsInv;
if (brs.some(br => br.__OriginalEnt__)) {
if (this._BoardProcessOption.highDrill
&& this._BoardProcessOption.highDrill.length > 1
&& !this._BoardProcessOption.highDrill.every(d => d === this._BoardProcessOption.drillType))
dridatas = this._BoardProcessOption.highDrill;
&& !this._BoardProcessOption.highDrill.every(d => d === this._BoardProcessOption.drillType)) {
highDrills = this._BoardProcessOption.highDrill;
}
ocsInv = this.OCSInv;
}
//拆单或者bbs的时候会重新加入最新的原板件的排钻和层板钉数据
@@ -20138,29 +20150,34 @@ exports.Board = Board_1 = class Board extends exports.ExtrudeSolid {
br._LayerNails = [...this._LayerNails];
br.ProcessingGroupList = [...this.ProcessingGroupList];
br._BoardProcessOption = { ...this._BoardProcessOption };
let new2old_edgeMap;
//修正排钻边的数据
if (dridatas) {
if (highDrills) {
br.BoardProcessOption.highDrill = []; //因为上面用了拷贝,所以这里不能直接改它的数据(我们新建一个数组来改它,否则原始板件的数据就被改掉了)
//矩阵对齐
let m = br.OCS.premultiply(ocsInv);
for (let i = 0; i < br.contourCurve.EndParam; i++) {
let p = br.contourCurve.GetPointAtParam(i + 0.5);
p.applyMatrix4(m);
let cp = this.contourCurve.GetClosestPointTo(p, false);
let cparam = this.contourCurve.GetParamAtPoint2(cp);
if (cparam !== undefined) {
let newDri = dridatas[Math.floor(cparam)];
br._BoardProcessOption.highDrill[i] = newDri ?? br._BoardProcessOption.drillType;
}
new2old_edgeMap = ParseNewBr2OldBr_EdgeMap(br, this, ocsInv);
for (let index of new2old_edgeMap) {
let dri = highDrills[index];
if (dri !== undefined)
br._BoardProcessOption.highDrill.push(dri);
else
br._BoardProcessOption.highDrill[i] = br._BoardProcessOption.drillType;
br._BoardProcessOption.highDrill.push(br._BoardProcessOption.drillType);
}
}
else //填充默认类型就好了
br._BoardProcessOption.highDrill = Array(br.contourCurve.EndParam).fill(br._BoardProcessOption.drillType);
//如果是矩形板,关联切割后的板件,用上下左右封边重新填充高级封边,避免近乎矩形的板件封边看上去不对 #I2AQ9R
// if (this.isRect) 由于异形也会被破坏,导致封边结果错误,对于异形也退化到矩形封边
br._BoardProcessOption.highSealed.length = 0;
br._BoardProcessOption.highSealed = []; //不直接修改它,避免原始板被修改
if (!this.isRect
&& this._BoardProcessOption.highSealed.length) {
new2old_edgeMap = new2old_edgeMap ?? ParseNewBr2OldBr_EdgeMap(br, this, ocsInv);
for (let index of new2old_edgeMap) {
let seal = this._BoardProcessOption.highSealed[index];
if (seal !== undefined)
br._BoardProcessOption.highSealed.push(seal);
else
br._BoardProcessOption.highSealed.push(this._BoardProcessOption.highSealed[0]);
}
}
}
}
return brs;
@@ -20441,11 +20458,33 @@ exports.Board = Board_1 = class Board extends exports.ExtrudeSolid {
}
else {
if (this.isRect)
InitRectBoardHoleOption(this, TempRectHoleOption);
ParseBoardRectHoleType(this, TempRectHoleOption);
else //之前不是异形,现在也不是异形时,对排钻边和封边进行映射,避免错误
{
let size = cu.BoundingBox.getSize(new three.Vector3);
let isRect = equaln$1(size.x * size.y, cu.Area, 0.1);
if (!isRect) {
let indexMap = [];
for (let i = 0; i < cu.EndParam; i++) {
let p = cu.GetPointAtParam(i + 0.5);
let cp = this.contourCurve.GetClosestPointTo(p, false);
let cparam = this.contourCurve.GetParamAtPoint2(cp);
indexMap.push(Math.floor(cparam));
}
let highDrill = [];
let highSealed = [];
for (let index of indexMap) {
highDrill.push(this._BoardProcessOption.highDrill[index] ?? this._BoardProcessOption.drillType);
highSealed.push(this._BoardProcessOption.highSealed[index] ?? 0);
}
this._BoardProcessOption.highDrill = highDrill;
this._BoardProcessOption.highSealed = highSealed;
}
}
}
super.ContourCurve = cu;
if (this.isRect && TempRectHoleOption.up)
SetRectHighHole(this, TempRectHoleOption);
SetBrHighHoleTypeFromRectHoleType(this, TempRectHoleOption);
}
Explode() {
return Board2Regions(this);
@@ -20461,8 +20500,8 @@ exports.Board = Board_1 = class Board extends exports.ExtrudeSolid {
return this;
this.WriteAllObjectRecord();
let highSeals;
if (this.isRect)
highSeals = GetBoardHighSeal(this, GetBoardSealingCurves(this));
// if (this.isRect)
highSeals = GetBoardHighSeal(this, GetBoardSealingCurves(this));
let a = Math.atan2(x.y, x.x);
if (isKeepLines && this.BoardProcessOption.lines !== LinesType.CanReversal && (equaln$1(x.y, 1, 1e-5) || equaln$1(x.y, -1, 1e-5)))
this.BoardProcessOption.lines = 1 - this.BoardProcessOption.lines; //翻转纹路 1=>0 0=>1
@@ -20479,8 +20518,8 @@ exports.Board = Board_1 = class Board extends exports.ExtrudeSolid {
this.CheckContourCurve();
if (this.contourCurve instanceof exports.Polyline)
this.contourCurve.UpdateOCSTo(IdentityMtx4);
if (this.isRect)
HandleRectBoardSealingData(this, highSeals); //这里不可以用缓存的曲线 否则分析错误,必须重新开始分析曲线
// if (this.isRect)
HandleRectBoardSealingData(this, highSeals); //这里不可以用缓存的曲线 否则分析错误,必须重新开始分析曲线
this.Update();
return this;
}
@@ -20540,7 +20579,7 @@ exports.Board = Board_1 = class Board extends exports.ExtrudeSolid {
else
this.BoardProcessOption[EBoardKeyList.BigHole] = 1 - this.BoardProcessOption[EBoardKeyList.BigHole]; //反转大孔面
this.BoardProcessOption.highSealed = highSeals;
if (!hasSplitSize && this.isRect)
if (!hasSplitSize) //&& this.isRect
HandleRectBoardSealingData(this, highSeals);
//重新构建SpaceOCS
this._SpaceOCS.multiplyMatrices(this._Matrix, new three.Matrix4().getInverse(this.RotateMat));
@@ -21088,6 +21127,21 @@ __decorate([
exports.Board = Board_1 = __decorate([
Factory
], exports.Board);
//解析新的板的边映射到旧板边的映射情况
function ParseNewBr2OldBr_EdgeMap(newBr, oldBr, oldBrOcsInv) {
let newBrCu = newBr.ContourCurve;
let oldBrCu = oldBr.ContourCurve;
let indexMap = [];
//矩阵对齐
let m = newBr.OCS.premultiply(oldBrOcsInv);
for (let i = 0; i < newBrCu.EndParam; i++) {
let p = newBrCu.GetPointAtParam(i + 0.5).applyMatrix4(m);
let cp = oldBrCu.GetClosestPointTo(p, false);
let cparam = oldBrCu.GetParamAtPoint2(cp);
indexMap.push(Math.floor(cparam));
}
return indexMap;
}
const COMPARE_FUNC = (sparam, range) => sparam - range[0];
//寻找插入位置
@@ -22689,7 +22743,7 @@ function UpdateHoleFakerWallsAndUpdateDraw(hole) {
return;
let fakerWalls = hole.RelevancyWalls.map(w => w.Object.Clone());
let pts = hole.Points;
if (pts.length < 2) {
if (pts.length < 2 || fakerWalls.length !== pts.length - 1) {
hole.Erase();
return;
}
@@ -26154,7 +26208,7 @@ exports.TemplateFilletAction = class TemplateFilletAction extends exports.Templa
if (cu instanceof exports.Circle)
return;
let fillet = new FilletUtils();
fillet.FilletRadius = Math.max(newValue, 0.1);
fillet.FilletRadius = Math.max(Math.abs(newValue), 0.1);
let cuOld = cu;
for (let arcParam of d.ArcParams) {
let param1 = FixIndex$1(arcParam - 1, cu.EndParam);
@@ -26164,8 +26218,11 @@ exports.TemplateFilletAction = class TemplateFilletAction extends exports.Templa
let res1 = new PromptEntityResult(cu, p1);
let res2 = new PromptEntityResult(cu, p2);
let fres = fillet.FilletPolyLineSelf(res1, res2);
if (fres)
if (fres) {
cu = fres.cu1;
if (newValue < 0)
cu.LineData[Math.floor(arcParam)].bul *= -1;
}
}
if (br instanceof exports.ExtrudeSolid) {
if (cu !== cuOld)
@@ -27201,6 +27258,7 @@ exports.TemplateRecord = TemplateRecord_1 = class TemplateRecord extends SymbolT
}
//删除材质变量(材质变量仅在KJL导入中使用,重新出现在右侧列表中是不明智的?) (但是用户可能编辑更新了它?)
// arrayRemoveIf(this.Params, p => p.type === TemplateParamType.Material);
this.UpdateEntitys();
//变换到新的模版空间
for (let en of ens) {
en.ApplyMatrix(this._CacheSpaceCS);
@@ -27221,6 +27279,8 @@ exports.TemplateRecord = TemplateRecord_1 = class TemplateRecord extends SymbolT
ent.SpaceOCS = this._CacheSpaceCS;
}
}
//在模块更新回模块空间之前更新实体(请参考左右侧板模块)
UpdateEntitys() { }
/**
* 使用PXPYPZ更新空间位置
*/
@@ -29735,14 +29795,17 @@ class CameraUpdate {
this.Update();
if (ver > 1)
this.CameraType = file.Read();
if (ver > 2)
this.Fov = file.Read();
}
//对象将自身数据写入到文件.
WriteFile(file) {
file.Write(2);
file.Write(3);
file.Write(this._ViewHeight);
file.Write(this._Target.toArray());
file.Write(this._Direction.toArray());
file.Write(this.CameraType);
file.Write(this.Fov);
}
}
@@ -29969,7 +30032,7 @@ exports.ViewportEntity = ViewportEntity_1 = class ViewportEntity extends exports
let renderType = en.IsOnlyRender ? this._renderType + 100 : this._renderType;
let o = en.GetDrawObjectFromRenderType(renderType);
if (!o) {
console.warn(`该实体${renderType}类型不存在`);
console.warn(`该实体渲染类型${renderType}类型不存在`);
return;
}
cloneObject.children.push(o);
@@ -34578,18 +34641,15 @@ exports.TemplateLeftRightBoardRecord = class TemplateLeftRightBoardRecord extend
this.Params.push(rparam);
return this;
}
async Update() {
UpdateEntitys() {
let [lId, rId] = this.Objects;
if (!lId || lId.IsErase || !rId || rId.IsErase)
return;
let lBr = lId.Object;
let rBr = rId.Object;
let ls = this.GetParam("ZS")?.value ?? 0;
lBr.Position = lBr.Position.sub(new three.Vector3(0, ls));
await super.Update();
let thickness = this.GetParam("BH")?.value ?? 18;
ls = this.GetParam("ZS")?.value ?? 0;
let rs = this.GetParam("YS")?.value ?? 0;
let zs = this.GetParam("ZS")?.value ?? 0; //左缩
let ys = this.GetParam("YS")?.value ?? 0; //右缩
lBr.Thickness = thickness;
rBr.Thickness = thickness;
if (!this._CacheSpaceSize) {
@@ -34598,16 +34658,10 @@ exports.TemplateLeftRightBoardRecord = class TemplateLeftRightBoardRecord extend
}
lBr.Height = this._CacheSpaceSize.z;
rBr.Height = this._CacheSpaceSize.z;
lBr.Width = this._CacheSpaceSize.y - ls;
rBr.Width = this._CacheSpaceSize.y - rs;
lBr.Position = lBr.Position.add(new three.Vector3(0, ls));
let x = new three.Vector3().setFromMatrixColumn(this._CacheSpaceCS, 0);
let y = new three.Vector3().setFromMatrixColumn(this._CacheSpaceCS, 1);
x.multiplyScalar(this._CacheSpaceSize.x - lBr.Thickness);
rBr.Position = lBr.Position.sub(y.multiplyScalar(ls - rs)).add(x);
//保持SpaceCS
for (let ent of [lBr, rBr])
ent.SpaceOCS = this._CacheSpaceCS;
lBr.Width = this._CacheSpaceSize.y - zs;
rBr.Width = this._CacheSpaceSize.y - ys;
lBr.Position = new three.Vector3(0, zs, 0);
rBr.Position = new three.Vector3(this._CacheSpaceSize.x - rBr.Thickness, ys, 0);
}
ReadFile(file) {
super.ReadFile(file);
@@ -37185,6 +37239,7 @@ function UpdateStartEndPoint(curve) {
}
exports.AxisCS = AxisCS;
exports.BUL_IS_LINE_FUZZ = BUL_IS_LINE_FUZZ;
exports.CADFactory = CADFactory;
exports.CADFiler = CADFiler;
exports.CURVE_FACE_TYPE_KEY = CURVE_FACE_TYPE_KEY;