|
|
@ -1,5 +1,5 @@
|
|
|
|
import Geom3 from '@jscad/modeling/src/geometries/geom3/type';
|
|
|
|
import Geom3 from '@jscad/modeling/src/geometries/geom3/type';
|
|
|
|
import { BufferAttribute, BufferGeometry, Euler, FrontSide, Frustum, Geometry, LineSegments, Matrix3, Matrix4, Mesh, Object3D, ShapeGeometry, Line as TLine, UVGenerator, Vector2, Vector3 } from 'three';
|
|
|
|
import { BufferAttribute, BufferGeometry, Euler, FrontSide, Frustum, Geometry, LineSegments, Matrix3, Matrix4, Mesh, Object3D, ShapeGeometry, Line as TLine, UVGenerator, Vector3 } from 'three';
|
|
|
|
import { ArcBoardBuild } from '../../Add-on/ArcBoard/ArcBoardBuild';
|
|
|
|
import { ArcBoardBuild } from '../../Add-on/ArcBoard/ArcBoardBuild';
|
|
|
|
import { ArcBoardOptions, ParseBoardArcFeed, defultArcBoardOption } from '../../Add-on/ArcBoard/ArcBoardFeeding';
|
|
|
|
import { ArcBoardOptions, ParseBoardArcFeed, defultArcBoardOption } from '../../Add-on/ArcBoard/ArcBoardFeeding';
|
|
|
|
import { SplitBoardSideModelUtil } from '../../Add-on/BoardCutting/SplitBoardSideModel';
|
|
|
|
import { SplitBoardSideModelUtil } from '../../Add-on/BoardCutting/SplitBoardSideModel';
|
|
|
@ -9,7 +9,7 @@ import { DrillType, FaceDirection } from "../../Add-on/DrawDrilling/DrillType";
|
|
|
|
import { CyHoleInBoard, IBoardRectHoleType, ParseBoardRectHoleType, SetBrHighHoleTypeFromRectHoleType } from '../../Add-on/DrawDrilling/HoleUtils';
|
|
|
|
import { CyHoleInBoard, IBoardRectHoleType, ParseBoardRectHoleType, SetBrHighHoleTypeFromRectHoleType } from '../../Add-on/DrawDrilling/HoleUtils';
|
|
|
|
import { HostApplicationServices } from '../../ApplicationServices/HostApplicationServices';
|
|
|
|
import { HostApplicationServices } from '../../ApplicationServices/HostApplicationServices';
|
|
|
|
import { AddEntityDrawObject } from '../../Common/AddEntityDrawObject';
|
|
|
|
import { AddEntityDrawObject } from '../../Common/AddEntityDrawObject';
|
|
|
|
import { arrayClone, arrayPushArray, arrayRemoveDuplicateBySort, arrayRemoveIf, arraySortByNumber, arraySum } from '../../Common/ArrayExt';
|
|
|
|
import { arrayLast, arrayPushArray, arrayRemoveDuplicateBySort, arrayRemoveIf, arraySortByNumber, arraySum } from '../../Common/ArrayExt';
|
|
|
|
import { EBoardKeyList } from '../../Common/BoardKeyList';
|
|
|
|
import { EBoardKeyList } from '../../Common/BoardKeyList';
|
|
|
|
import { Geom3Res } from '../../Common/CSGIntersect';
|
|
|
|
import { Geom3Res } from '../../Common/CSGIntersect';
|
|
|
|
import { ColorMaterial } from '../../Common/ColorPalette';
|
|
|
|
import { ColorMaterial } from '../../Common/ColorPalette';
|
|
|
@ -28,7 +28,7 @@ import { Box3Ext } from '../../Geometry/Box';
|
|
|
|
import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils';
|
|
|
|
import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils';
|
|
|
|
import { AddCSGSubtractTask, CSGTask, TerminateCSGTask } from '../../Geometry/CSGSubtract/CSGSubtractTaskManager';
|
|
|
|
import { AddCSGSubtractTask, CSGTask, TerminateCSGTask } from '../../Geometry/CSGSubtract/CSGSubtractTaskManager';
|
|
|
|
import { EdgesGeometry } from '../../Geometry/EdgeGeometry';
|
|
|
|
import { EdgesGeometry } from '../../Geometry/EdgeGeometry';
|
|
|
|
import { AsVector2, AsVector3, IdentityMtx4, XAxis, XAxisN, YAxis, YAxisN, ZAxis, ZeroVec, equaln, equalv3 } from '../../Geometry/GeUtils';
|
|
|
|
import { AsVector2, AsVector3, IdentityMtx4, XAxis, XAxisN, YAxis, YAxisN, ZAxis, ZeroVec, equaln, equalv2, equalv3 } from '../../Geometry/GeUtils';
|
|
|
|
import { PointShapeUtils } from '../../Geometry/PointShapeUtils';
|
|
|
|
import { PointShapeUtils } from '../../Geometry/PointShapeUtils';
|
|
|
|
import { GetBoardContour, GetBoardHighSeal, GetBoardSealingCurves, GetHighBoardEdgeRemark, SetBoardEdgeRemarkData, SetBoardTopDownLeftRightSealData } from '../../GraphicsSystem/CalcEdgeSealing';
|
|
|
|
import { GetBoardContour, GetBoardHighSeal, GetBoardSealingCurves, GetHighBoardEdgeRemark, SetBoardEdgeRemarkData, SetBoardTopDownLeftRightSealData } from '../../GraphicsSystem/CalcEdgeSealing';
|
|
|
|
import { RenderType } from '../../GraphicsSystem/RenderType';
|
|
|
|
import { RenderType } from '../../GraphicsSystem/RenderType';
|
|
|
@ -161,19 +161,15 @@ export class Board extends ExtrudeSolid
|
|
|
|
//二维刀路 id -> polyline
|
|
|
|
//二维刀路 id -> polyline
|
|
|
|
private _KnifePolylineMap: Map<string, Polyline> = new Map();
|
|
|
|
private _KnifePolylineMap: Map<string, Polyline> = new Map();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private _jigSweepPath: Polyline; // 拖拽时见光面的SweepPath
|
|
|
|
|
|
|
|
private _jigPath2WCSMtx: Matrix4; // 拖拽时路径转世界坐标系矩阵
|
|
|
|
|
|
|
|
|
|
|
|
constructor()
|
|
|
|
constructor()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
super();
|
|
|
|
super();
|
|
|
|
this.InitBoardData();
|
|
|
|
this.InitBoardData();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
override CheckContourCurve()
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
super.CheckContourCurve();
|
|
|
|
|
|
|
|
if (this._SweepPath && !this._FixContourByArcSweepPath_Ing)
|
|
|
|
|
|
|
|
this.FixArcSweepPathLength();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
get BoundingBoxInOCS()
|
|
|
|
get BoundingBoxInOCS()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (this._SweepPath)
|
|
|
|
if (this._SweepPath)
|
|
|
@ -192,6 +188,56 @@ export class Board extends ExtrudeSolid
|
|
|
|
this._isDrawArcGroove = v;
|
|
|
|
this._isDrawArcGroove = v;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* path 发生改变,更新圆弧配置
|
|
|
|
|
|
|
|
* @param {{ key: number, arc: Arc; }[]} oldArcs 旧圆弧和对应的board options key
|
|
|
|
|
|
|
|
* @param {Polyline} nPath 新路径(未进行起点偏移)
|
|
|
|
|
|
|
|
* @return {*} {void}
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private UpdateArcBoardOptionsByPath(oldArcs: { key: number, arc: Arc; }[], nPath: Polyline): void
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (oldArcs.length === 0) return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const nCurves = nPath.Explode();
|
|
|
|
|
|
|
|
const newArcs: { key: number, arc: Arc; }[] = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < nCurves.length; i++)
|
|
|
|
|
|
|
|
if (nCurves[i] instanceof Arc)
|
|
|
|
|
|
|
|
newArcs.push({ key: i, arc: nCurves[i] as Arc });
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const newOpts = new Map<number, ArcBoardOptions>();
|
|
|
|
|
|
|
|
const oldOpts = this._ArcBoardOptions;
|
|
|
|
|
|
|
|
newOpts.set(-1, oldOpts.get(-1));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 设置新圆弧对应的原始配置
|
|
|
|
|
|
|
|
for (let i = 0; i < newArcs.length; i++)
|
|
|
|
|
|
|
|
for (const item of oldArcs)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const oldArc = item.arc;
|
|
|
|
|
|
|
|
const oldKey = item.key;
|
|
|
|
|
|
|
|
const newArc = newArcs[i].arc;
|
|
|
|
|
|
|
|
const newKey = newArcs[i].key;
|
|
|
|
|
|
|
|
if (equalv3(newArc.StartPoint, oldArc.StartPoint, 1e-5) || equalv3(newArc.EndPoint, oldArc.EndPoint, 1e-5)) // 若圆弧的头或尾部位置相同,说明是同一段圆弧
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
newOpts.set(newKey, { ...oldOpts.get(oldKey), arcLength: parseFloat(FixedNotZero(newArc.Length, 5)) });
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 曲线从头拉到尾部后面,或者从尾拉到头部前面
|
|
|
|
|
|
|
|
if (newArcs.length === 1 && newOpts.size === 1)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let oldArcIndex = 0;// 第一个圆弧
|
|
|
|
|
|
|
|
if (equalv3(newArcs[0].arc.StartPoint, arrayLast(oldArcs).arc.EndPoint, 1e-3)) // 从头拉伸到尾部后面,则新圆弧的起点和旧圆弧的尾点相等。
|
|
|
|
|
|
|
|
oldArcIndex = oldArcs.length - 1; // 最后一个圆弧
|
|
|
|
|
|
|
|
const oldKey = oldArcs[oldArcIndex].key;
|
|
|
|
|
|
|
|
const newKey = newArcs[0].key;
|
|
|
|
|
|
|
|
newOpts.set(newKey, { ...oldOpts.get(oldKey), arcLength: parseFloat(FixedNotZero(newArcs[0].arc.Length, 5)) });
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._ArcBoardOptions.clear();
|
|
|
|
|
|
|
|
this._ArcBoardOptions = newOpts;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
get ArcBoardOptions()
|
|
|
|
get ArcBoardOptions()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (this._ArcBoardOptions.size > 0)
|
|
|
|
if (this._ArcBoardOptions.size > 0)
|
|
|
@ -2191,6 +2237,7 @@ export class Board extends ExtrudeSolid
|
|
|
|
|| renderType === RenderType.CustomNumber //自定义编号
|
|
|
|
|| renderType === RenderType.CustomNumber //自定义编号
|
|
|
|
|| renderType === RenderType.CustomNumberPrint//自定义编号打印
|
|
|
|
|| renderType === RenderType.CustomNumberPrint//自定义编号打印
|
|
|
|
|| renderType === RenderType.ModelGroove //造型槽
|
|
|
|
|| renderType === RenderType.ModelGroove //造型槽
|
|
|
|
|
|
|
|
|| this.IsEmbedEntity && !this.ParentEntity.objectId // 复合实体
|
|
|
|
)
|
|
|
|
)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
obj = new Object3D();
|
|
|
|
obj = new Object3D();
|
|
|
@ -2207,22 +2254,25 @@ export class Board extends ExtrudeSolid
|
|
|
|
|
|
|
|
|
|
|
|
UpdateDrawObject(renderType: RenderType, obj: Object3D)
|
|
|
|
UpdateDrawObject(renderType: RenderType, obj: Object3D)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (this._SweepPath && renderType === RenderType.Jig)
|
|
|
|
// 圆弧板和复合实体内的圆弧板,Jig时,实时显示见光面路径
|
|
|
|
// if (this._SweepPath)
|
|
|
|
if (this._SweepPath && (renderType === RenderType.Jig || this.IsEmbedEntity && !this.ParentEntity.objectId))
|
|
|
|
{
|
|
|
|
{
|
|
|
|
DisposeThreeObj(obj);
|
|
|
|
DisposeThreeObj(obj);
|
|
|
|
Object3DRemoveAll(obj);
|
|
|
|
Object3DRemoveAll(obj);
|
|
|
|
let pts = this._SweepPath.Shape.getPoints().map(AsVector3);
|
|
|
|
|
|
|
|
for (let p of pts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
p.z = p.y;
|
|
|
|
|
|
|
|
p.y = 0;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
if (!this._jigSweepPath)
|
|
|
|
p.applyMatrix4(this.ArcBuild.Rotate2OCSMtx);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let geo = new BufferGeometry().setFromPoints(pts);
|
|
|
|
const path2BoardMtx = new Matrix4();
|
|
|
|
obj.add(new TLine(geo, ColorMaterial.GetLineMaterial(this.DrawColorIndex)));
|
|
|
|
const invMtx = new Matrix4().getInverse(this._Matrix);
|
|
|
|
|
|
|
|
path2BoardMtx.multiplyMatrices(invMtx, this._jigPath2WCSMtx);
|
|
|
|
|
|
|
|
const pts = this._jigSweepPath.Shape.getPoints().map(AsVector3);
|
|
|
|
|
|
|
|
const geo = new BufferGeometry().setFromPoints(pts);
|
|
|
|
|
|
|
|
const line = new TLine(geo, ColorMaterial.GetLineMaterial(this.ColorIndex));
|
|
|
|
|
|
|
|
line.matrix = path2BoardMtx;
|
|
|
|
|
|
|
|
obj.add(line);
|
|
|
|
|
|
|
|
this._jigSweepPath = undefined;
|
|
|
|
|
|
|
|
this._jigPath2WCSMtx = undefined;
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2522,30 +2572,17 @@ export class Board extends ExtrudeSolid
|
|
|
|
override GetGripPoints(): Vector3[]
|
|
|
|
override GetGripPoints(): Vector3[]
|
|
|
|
{
|
|
|
|
{
|
|
|
|
let pts = super.GetGripPoints();
|
|
|
|
let pts = super.GetGripPoints();
|
|
|
|
|
|
|
|
pts = this.MapToArcPoints(pts, DragPointType.Grip);
|
|
|
|
|
|
|
|
return pts;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private MapToArcPoints(pts: Vector3[], dragPointType: DragPointType): Vector3[]
|
|
|
|
|
|
|
|
{
|
|
|
|
if (this._SweepPath)
|
|
|
|
if (this._SweepPath)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (!this._SweepArcBoardBuild)
|
|
|
|
if (!this._SweepArcBoardBuild)
|
|
|
|
this._SweepArcBoardBuild = new ArcBoardBuild(this);
|
|
|
|
this._SweepArcBoardBuild = new ArcBoardBuild(this);
|
|
|
|
|
|
|
|
|
|
|
|
if (false)//暂时放弃这个直接拉伸路径的功能
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// if (!this._SweepArcBoardBuild)
|
|
|
|
|
|
|
|
// {
|
|
|
|
|
|
|
|
// this._SweepArcBoardBuild = new ArcBoardBuild(this);
|
|
|
|
|
|
|
|
// this._SweepArcBoardBuild.ParseSweepCurves();
|
|
|
|
|
|
|
|
// }
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let pts = this._SweepPath.GetGripPoints();
|
|
|
|
|
|
|
|
for (let p of pts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
[p.y, p.z] = [p.z, p.y];//映射点
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
p.applyMatrix4(this._SweepArcBoardBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
p.applyMatrix4(this.OCSNoClone);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return pts;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let inv = this.OCSInv;
|
|
|
|
let inv = this.OCSInv;
|
|
|
|
let mtx = this.OCSNoClone;
|
|
|
|
let mtx = this.OCSNoClone;
|
|
|
|
if (this._SweepArcBoardBuild._OCS2RotateMtx)
|
|
|
|
if (this._SweepArcBoardBuild._OCS2RotateMtx)
|
|
|
@ -2567,10 +2604,8 @@ export class Board extends ExtrudeSolid
|
|
|
|
this._SweepArcBoardBuild.PosMap2ArcPos(p);
|
|
|
|
this._SweepArcBoardBuild.PosMap2ArcPos(p);
|
|
|
|
p.applyMatrix4(mtx);
|
|
|
|
p.applyMatrix4(mtx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if (this.HasSideModel)
|
|
|
|
|
|
|
|
this.AddSideModelGripPoints(pts, dragPointType);
|
|
|
|
if (this.HasSideModel)
|
|
|
|
|
|
|
|
this.AddSideModelGripPoints(pts, DragPointType.Grip);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return pts;
|
|
|
|
return pts;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -2578,101 +2613,25 @@ export class Board extends ExtrudeSolid
|
|
|
|
override MoveGripPoints(indexList: number[], vec: Vector3): void
|
|
|
|
override MoveGripPoints(indexList: number[], vec: Vector3): void
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (indexList.length === 0) return;
|
|
|
|
if (indexList.length === 0) return;
|
|
|
|
|
|
|
|
this.ClearSideModelingCache();
|
|
|
|
if (this._SweepPath)
|
|
|
|
if (this._SweepPath)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
this.WriteAllObjectRecord();
|
|
|
|
this.MoveArcBoardPoints(indexList, vec, DragPointType.Grip);
|
|
|
|
if (false)//暂时放弃这个直接拉伸路径的功能
|
|
|
|
this.Update();
|
|
|
|
{
|
|
|
|
|
|
|
|
vec = TransformVector(vec.clone(), this.OCSInv);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
TransformVector(vec, this.ArcBuild.OCS2RotateMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[vec.y, vec.z] = [vec.z, -vec.y];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._SweepPath.MoveGripPoints(indexList, vec);
|
|
|
|
|
|
|
|
let sp = this._SweepPath.StartPoint;
|
|
|
|
|
|
|
|
if (!equalv3(sp, ZeroVec))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (let i = 0; i < this._SweepPath.LineData.length; i++)
|
|
|
|
|
|
|
|
this._SweepPath.LineData[i].pt.sub(sp as unknown as Vector2);
|
|
|
|
|
|
|
|
this._SweepPath.OCSNoClone.identity();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let [y, z] = [sp.y, sp.z];
|
|
|
|
|
|
|
|
sp.z = y;
|
|
|
|
|
|
|
|
sp.y = -z;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
TransformVector(sp, this.ArcBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TransformVector(sp, this.OCSNoClone);
|
|
|
|
|
|
|
|
this.Move(sp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (this.objectId)
|
|
|
|
|
|
|
|
this.FixContourByArcSweepPath();
|
|
|
|
|
|
|
|
this.Update();
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
this.ClearSideModelingCache();
|
|
|
|
super.MoveGripPoints(indexList, vec);
|
|
|
|
super.MoveGripPoints(indexList, vec);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
GetStretchPoints()
|
|
|
|
GetStretchPoints()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (this._SweepPath)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let spts = this._SweepPath.GetStretchPoints();
|
|
|
|
|
|
|
|
let pts: Vector3[] = [];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!this._SweepArcBoardBuild)
|
|
|
|
|
|
|
|
this._SweepArcBoardBuild = new ArcBoardBuild(this);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let p of spts)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
[p.y, p.z] = [p.z, p.y];//映射点
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
p.applyMatrix4(this._SweepArcBoardBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
pts.push(p);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let brWidth: number;
|
|
|
|
|
|
|
|
if (this._SweepAngle === 0)
|
|
|
|
|
|
|
|
brWidth = this.height;
|
|
|
|
|
|
|
|
else if (equaln(Math.abs(this._SweepAngle), Math.PI / 2))
|
|
|
|
|
|
|
|
brWidth = this.width;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let con = this.ContourCurve.Clone();
|
|
|
|
|
|
|
|
let ro = new Matrix4().makeRotationZ(-this._SweepAngle);
|
|
|
|
|
|
|
|
con.ApplyMatrix(ro);
|
|
|
|
|
|
|
|
let box = con.BoundingBox;
|
|
|
|
|
|
|
|
brWidth = box.max.y - box.min.y;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let v = new Vector3(0, brWidth, 0);
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
TransformVector(v, this._SweepArcBoardBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let p of spts)
|
|
|
|
|
|
|
|
pts.push(p.clone().add(v));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
for (let p of pts)
|
|
|
|
|
|
|
|
p.applyMatrix4(this.OCSNoClone);
|
|
|
|
|
|
|
|
return pts;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let pts = this.GetGripOrStretchPoints(DragPointType.Stretch);
|
|
|
|
let pts = this.GetGripOrStretchPoints(DragPointType.Stretch);
|
|
|
|
|
|
|
|
pts = this.MapToArcPoints(pts, DragPointType.Stretch);
|
|
|
|
for (let m of this._2DModelingList)
|
|
|
|
for (let m of this._2DModelingList)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
pts.push(...m.path.GetStretchPoints().map(p => p.add(new Vector3(0, 0, m.dir === FaceDirection.Front ? this.thickness : 0)).applyMatrix4(this.OCSNoClone)));
|
|
|
|
pts.push(...m.path.GetStretchPoints().map(p => p.add(new Vector3(0, 0, m.dir === FaceDirection.Front ? this.thickness : 0)).applyMatrix4(this.OCSNoClone)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this.HasSideModel)
|
|
|
|
|
|
|
|
this.AddSideModelGripPoints(pts, DragPointType.Stretch);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return pts;
|
|
|
|
return pts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
@ -2685,147 +2644,6 @@ export class Board extends ExtrudeSolid
|
|
|
|
undoData.WriteObjectHistoryPath(this, new HistorycRecord);
|
|
|
|
undoData.WriteObjectHistoryPath(this, new HistorycRecord);
|
|
|
|
return;
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepPath)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (false)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.WriteAllObjectRecord();
|
|
|
|
|
|
|
|
let stretchCount = this._SweepPath.GetDragPointCount(DragPointType.Stretch);
|
|
|
|
|
|
|
|
//Move
|
|
|
|
|
|
|
|
if (indexList.length === stretchCount * 2)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.Position = this.Position.add(vec);
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
vec = vec.clone();
|
|
|
|
|
|
|
|
let inv = this.OCSInv.setPosition(0, 0, 0);
|
|
|
|
|
|
|
|
vec.applyMatrix4(inv);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
TransformVector(vec, this.ArcBuild.OCS2RotateMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const IsStretchThickness = (indexs: number[]) =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (indexs.length === stretchCount)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let isF = indexs[0] < stretchCount;
|
|
|
|
|
|
|
|
return indexs.every(i => isF === (i < stretchCount));
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
if (IsStretchThickness(indexList))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let isFront = indexList[0] < stretchCount;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (indexList.every(v => v < stretchCount === isFront))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function UnEqualProportionScale(cu: Curve, ref: number, dist: number, isFront: boolean)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (cu instanceof Polyline)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let lineData = cu.LineData;
|
|
|
|
|
|
|
|
let length = lineData.length;
|
|
|
|
|
|
|
|
let p = cu.Position.y;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let moveIndexs: number[] = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < length; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (isFront ? (lineData[i].pt.y + p < ref) : (lineData[i].pt.y + p > ref))
|
|
|
|
|
|
|
|
moveIndexs.push(i);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
let moveVec = new Vector3();
|
|
|
|
|
|
|
|
moveVec.y = dist;
|
|
|
|
|
|
|
|
cu.MoveStretchPoints(moveIndexs, moveVec);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Change thickness
|
|
|
|
|
|
|
|
let con = this.ContourCurve.Clone();
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
con.ApplyMatrix(this.ArcBuild.OCS2RotateMtx);
|
|
|
|
|
|
|
|
(con as Polyline).UpdateOCSTo(new Matrix4);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let box = con.BoundingBox;
|
|
|
|
|
|
|
|
let size = box.max.y - box.min.y;
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// if (this.objectId)
|
|
|
|
|
|
|
|
// TestDraw(con.Clone(), 4);
|
|
|
|
|
|
|
|
let isSuccess = UnEqualProportionScale(con, size / 2, vec.y, isFront);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (this.objectId)
|
|
|
|
|
|
|
|
// TestDraw(con.Clone(), 3);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
con.ApplyMatrix(this.ArcBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let box = con.BoundingBox;
|
|
|
|
|
|
|
|
// if (this.objectId)
|
|
|
|
|
|
|
|
// TestDraw(con.Clone(), 2);
|
|
|
|
|
|
|
|
con.Move(box.min.clone().negate());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// if (this.objectId)
|
|
|
|
|
|
|
|
// TestDraw(con.Clone(), 1);
|
|
|
|
|
|
|
|
this.SetContourCurve(con);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// //移动位置而不改变内部拉槽
|
|
|
|
|
|
|
|
let v = box.min;
|
|
|
|
|
|
|
|
TransformVector(v, this.OCSNoClone);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._Matrix.elements[12] += v.x;
|
|
|
|
|
|
|
|
this._Matrix.elements[13] += v.y;
|
|
|
|
|
|
|
|
this._Matrix.elements[14] += v.z;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
indexList = arrayClone(indexList);
|
|
|
|
|
|
|
|
//修正点的索引
|
|
|
|
|
|
|
|
for (let i = 0; i < indexList.length; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
let index = indexList[i];
|
|
|
|
|
|
|
|
if (index >= stretchCount)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
index -= stretchCount;
|
|
|
|
|
|
|
|
indexList[i] = index;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
indexList = [...new Set(indexList)];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
[vec.y, vec.z] = [vec.z, -vec.y];
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._SweepPath.MoveStretchPoints(indexList, vec);
|
|
|
|
|
|
|
|
let sp = this._SweepPath.StartPoint;
|
|
|
|
|
|
|
|
if (!equalv3(sp, ZeroVec))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
for (let i = 0; i < this._SweepPath.LineData.length; i++)
|
|
|
|
|
|
|
|
this._SweepPath.LineData[i].pt.sub(sp as unknown as Vector2);
|
|
|
|
|
|
|
|
this._SweepPath.OCSNoClone.identity();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let [y, z] = [sp.y, sp.z];
|
|
|
|
|
|
|
|
sp.z = y;
|
|
|
|
|
|
|
|
sp.y = -z;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
TransformVector(sp, this.ArcBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
TransformVector(sp, this.OCSNoClone);
|
|
|
|
|
|
|
|
this.Move(sp);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this.FixContourByArcSweepPath();
|
|
|
|
|
|
|
|
this.Update();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return;//暂时屏蔽圆弧板的拉伸
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let exCount = arraySum(this.GetStrectchPointCountList(DragPointType.Stretch));
|
|
|
|
let exCount = arraySum(this.GetStrectchPointCountList(DragPointType.Stretch));
|
|
|
|
let originIndexList: number[] = [];
|
|
|
|
let originIndexList: number[] = [];
|
|
|
|
let mIndexList: number[] = [];
|
|
|
|
let mIndexList: number[] = [];
|
|
|
@ -2839,7 +2657,10 @@ export class Board extends ExtrudeSolid
|
|
|
|
|
|
|
|
|
|
|
|
let oldOcs = this.OCS;
|
|
|
|
let oldOcs = this.OCS;
|
|
|
|
|
|
|
|
|
|
|
|
super.MoveStretchPoints(originIndexList, vec);
|
|
|
|
if (this._SweepPath)
|
|
|
|
|
|
|
|
this.MoveArcBoardPoints(originIndexList, vec, DragPointType.Stretch);
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
super.MoveStretchPoints(originIndexList, vec);
|
|
|
|
|
|
|
|
|
|
|
|
if (!this.Id) return;
|
|
|
|
if (!this.Id) return;
|
|
|
|
|
|
|
|
|
|
|
@ -2991,6 +2812,257 @@ export class Board extends ExtrudeSolid
|
|
|
|
|
|
|
|
|
|
|
|
return pts;
|
|
|
|
return pts;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private MoveArcBoardPoints(indexList: Array<number>, vec: Vector3, dragType: DragPointType)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
this.WriteAllObjectRecord();
|
|
|
|
|
|
|
|
const isGrip = dragType === DragPointType.Grip;
|
|
|
|
|
|
|
|
const oldPts = isGrip ? this.GetGripPoints() : this.GetStretchPoints();
|
|
|
|
|
|
|
|
const MoveBack = () => isGrip ? super.MoveGripPoints(indexList, offsetVec.clone().negate()) : super.MoveStretchPoints(indexList, offsetVec.clone().negate());
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let path = this.ArcBuild.SweepPath1.Clone();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 1、计算沿着SweepPath偏移的向量
|
|
|
|
|
|
|
|
const offsetVec = this.GetOffsetVecAlongPath(oldPts[indexList[0]].clone(), vec, path);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const oldPos = this.Position;
|
|
|
|
|
|
|
|
const oldCon = this.ContourCurve.Clone();
|
|
|
|
|
|
|
|
const ocs2rot = this.ArcBuild.OCS2RotateMtx;
|
|
|
|
|
|
|
|
oldCon.ApplyMatrix(ocs2rot);
|
|
|
|
|
|
|
|
const oldBox = oldCon.BoundingBox;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 2、移动平板上的点
|
|
|
|
|
|
|
|
isGrip ? super.MoveGripPoints(indexList, offsetVec) : super.MoveStretchPoints(indexList, offsetVec);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const newPos = this.Position;
|
|
|
|
|
|
|
|
const conMoveVec = TransformVector(newPos.clone().sub(oldPos), this.OCSInv);//轮廓在OCS中移动的向量
|
|
|
|
|
|
|
|
const newCon = this.ContourCurve.Clone();
|
|
|
|
|
|
|
|
newCon.Move(conMoveVec);
|
|
|
|
|
|
|
|
newCon.ApplyMatrix(ocs2rot);
|
|
|
|
|
|
|
|
const newBox = newCon.BoundingBox;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._jigSweepPath = path.Clone();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 特殊场景:闭合SweepPath,其对应的首尾不能发生变化,否者会发生path和Contour映射错误。
|
|
|
|
|
|
|
|
if (path.CloseMark && !(equaln(newBox.min.x, oldBox.min.x) && equaln(newBox.max.x, oldBox.max.x)))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
MoveBack();// 若头尾被拖拽过,需要恢复回去
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 特殊场景:某些操作,对弧形板进行移动(如当拖拽中间点),未发生路径改变,则重新移动回去
|
|
|
|
|
|
|
|
const newSize = newBox.getSize(new Vector3);
|
|
|
|
|
|
|
|
const oldSize = oldBox.getSize(new Vector3);
|
|
|
|
|
|
|
|
if (equaln(newSize.x, oldSize.x, 1e-3))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const newPts = isGrip ? this.GetGripPoints() : this.GetStretchPoints();
|
|
|
|
|
|
|
|
if (oldPts.length === newPts.length)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const vec = oldPts[0].clone().sub(newPts[0]);
|
|
|
|
|
|
|
|
const isMoveArcBoard = oldPts.every((pt, i) => equalv3(pt.clone().sub(newPts[i]), vec));
|
|
|
|
|
|
|
|
if (isMoveArcBoard)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
MoveBack();
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 3、修正SweepPath
|
|
|
|
|
|
|
|
path = this.FixSweepPathByContourBondingbox(newBox, oldBox, path);
|
|
|
|
|
|
|
|
// 特殊场景:path 计算发生错误,需要恢复板的状态
|
|
|
|
|
|
|
|
if (!path)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
MoveBack();
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 4、计算弧形板偏移矩阵
|
|
|
|
|
|
|
|
if (this.objectId || (this.IsEmbedEntity && this.ParentEntity.objectId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const pts1 = isGrip ? newCon.GetGripPoints() : newCon.GetStretchPoints();
|
|
|
|
|
|
|
|
const pts2 = isGrip ? oldCon.GetGripPoints() : oldCon.GetStretchPoints();
|
|
|
|
|
|
|
|
const count = Math.min(pts1.length, pts2.length);
|
|
|
|
|
|
|
|
this._SweepArcBoardBuild = undefined;
|
|
|
|
|
|
|
|
for (let i = 0; i < count; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (equalv2(pts1[i], pts2[i], 1e-3)) // 找到新板和旧板上不变的点,计算出偏移矩阵
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const pts = isGrip ? this.GetGripPoints() : this.GetStretchPoints();
|
|
|
|
|
|
|
|
this.Move(oldPts[i].sub(pts[i]));
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this._SweepArcBoardBuild = undefined;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private GetOffsetVecAlongPath(oldP: Vector3, vec: Vector3, path: Polyline): Vector3
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const p = oldP.clone().add(vec);//拉伸后的点 在世界坐标系中
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const path2WCSMtx = new Matrix4().makeBasis(XAxis, ZAxis, YAxisN);
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
path2WCSMtx.premultiply(this.ArcBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
path2WCSMtx.premultiply(this.OCSNoClone);
|
|
|
|
|
|
|
|
const wcs2PathMtx = new Matrix4().getInverse(path2WCSMtx);
|
|
|
|
|
|
|
|
this._jigPath2WCSMtx = path2WCSMtx.clone();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//变换到路径坐标系
|
|
|
|
|
|
|
|
p.applyMatrix4(wcs2PathMtx);
|
|
|
|
|
|
|
|
oldP.applyMatrix4(wcs2PathMtx);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 限制p, 在见光面的曲面中,计算偏移向量
|
|
|
|
|
|
|
|
const cp = path.GetClosestPointTo(p, true);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const oldZ = oldP.z;
|
|
|
|
|
|
|
|
const newZ = p.z;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const oldPCp = path.GetClosestPointTo(oldP.setZ(0), false);//旧的最近点
|
|
|
|
|
|
|
|
const oldDist = path.GetDistAtPoint2(oldPCp);// 移动前的Dist
|
|
|
|
|
|
|
|
const movedDist = path.GetDistAtPoint2(cp);// 移动后的Dist
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const moveVec = new Vector3(movedDist - oldDist, - newZ + oldZ, 0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//将moveVec转换到世界坐标系
|
|
|
|
|
|
|
|
if (this._SweepAngle !== 0)
|
|
|
|
|
|
|
|
TransformVector(moveVec, this.ArcBuild.Rotate2OCSMtx);
|
|
|
|
|
|
|
|
TransformVector(moveVec, this.OCSNoClone);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return moveVec;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @private 通过新旧轮廓的Bondingbox修正路径
|
|
|
|
|
|
|
|
* @param {Box3Ext} newBox 路径坐标系下,新轮廓的Bondingbox
|
|
|
|
|
|
|
|
* @param {Box3Ext} oldBox 路径坐标系下,旧轮廓的Bondingbox
|
|
|
|
|
|
|
|
* @param {Polyline} path 见光面路径
|
|
|
|
|
|
|
|
* @return {*} {Polyline} 修正好的路径
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
private FixSweepPathByContourBondingbox(newBox: Box3Ext, oldBox: Box3Ext, path: Polyline): Polyline
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 若头部和尾部重合,则直接不处理
|
|
|
|
|
|
|
|
if (equaln(newBox.min.x, newBox.max.x, 0.1))
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const GetArcAndKeys = (): { key: number, arc: Arc; }[] =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const curves = path.Explode();
|
|
|
|
|
|
|
|
const arcs: { key: number, arc: Arc; }[] = [];
|
|
|
|
|
|
|
|
for (let i = 0; i < curves.length; i++)
|
|
|
|
|
|
|
|
if (curves[i] instanceof Arc)
|
|
|
|
|
|
|
|
arcs.push({ key: i, arc: curves[i].Clone() as Arc });
|
|
|
|
|
|
|
|
return arcs;
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
const arcKeys = GetArcAndKeys();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const MovePath = (pathToMove: Polyline, mVec: Vector3) =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 修正SWeepPath
|
|
|
|
|
|
|
|
pathToMove.Move(mVec);
|
|
|
|
|
|
|
|
const { pts: pathPts, buls } = pathToMove.MatrixAlignTo2(new Matrix4);
|
|
|
|
|
|
|
|
pathToMove.OCSNoClone.identity();
|
|
|
|
|
|
|
|
for (let i = 0; i < pathToMove.LineData.length; i++)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
pathToMove.LineData[i].pt.copy(pathPts[i]);
|
|
|
|
|
|
|
|
pathToMove.LineData[i].bul = buls[i];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
let jigSpt: Vector3 = undefined;
|
|
|
|
|
|
|
|
const FixHead = () =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!equaln(newBox.min.x, 0, 1e-3)) // 头部
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const c1 = path.GetCurveAtIndex(0);
|
|
|
|
|
|
|
|
if (newBox.min.x < 0)
|
|
|
|
|
|
|
|
path.Extend(newBox.min.x / c1.Length); // 延伸
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
path = path.GetSplitCurves(path.GetParamAtDist(newBox.min.x))[1]; // 裁剪
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
jigSpt = path.StartPoint.clone();
|
|
|
|
|
|
|
|
MovePath(path, path.StartPoint.clone().negate());// 修正Path
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const FixTail = () =>
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
if (!equaln(newBox.max.x, oldBox.max.x, 1e-3)) // 尾部
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const dist = newBox.max.x - oldBox.max.x;
|
|
|
|
|
|
|
|
const ce = path.GetCurveAtIndex(path.EndParam - 1);
|
|
|
|
|
|
|
|
if (dist > 0)
|
|
|
|
|
|
|
|
path.Extend(path.EndParam + ((dist) / ce.Length)); // 延伸
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
path = path.GetSplitCurves(path.GetParamAtDist(newBox.max.x - newBox.min.x))[0]; // 裁剪, PS: 从尾部点拉伸到头部点之前,newBox.min.x不为零
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* 某些异形板左侧头部拉伸到尾部后面示意图:
|
|
|
|
|
|
|
|
* ___________
|
|
|
|
|
|
|
|
* A | |
|
|
|
|
|
|
|
|
* |_______ |
|
|
|
|
|
|
|
|
* | |
|
|
|
|
|
|
|
|
* old B |___|
|
|
|
|
|
|
|
|
* _____
|
|
|
|
|
|
|
|
* | | A
|
|
|
|
|
|
|
|
* ___|_____|
|
|
|
|
|
|
|
|
* | |
|
|
|
|
|
|
|
|
* new B |___|
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
const outofTail = newBox.min.x >= oldBox.max.x
|
|
|
|
|
|
|
|
|| equaln(newBox.min.x, oldBox.max.x, 1e-3) // 矩形板:拉伸后,新板头和旧板尾部相同
|
|
|
|
|
|
|
|
|| newBox.min.x > oldBox.min.x && newBox.max.x > oldBox.max.x; // 某些异形板:新板头会在旧板中间某处,新板尾超过旧版尾
|
|
|
|
|
|
|
|
if (outofTail)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
// 头部拉伸在超过尾部,即新头部大于等于原尾部。则先对尾部延伸,再裁剪头部(若先裁剪头部,则path可能会为空)
|
|
|
|
|
|
|
|
FixTail();
|
|
|
|
|
|
|
|
FixHead();
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
FixHead();
|
|
|
|
|
|
|
|
FixTail();
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 计算 this._SweepPath
|
|
|
|
|
|
|
|
let sweepPath = undefined;
|
|
|
|
|
|
|
|
if (this._SweepVisibleFace === FaceDirection.Back)
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sweepPath = path;
|
|
|
|
|
|
|
|
// 做offset偏移,查看path是否会被裁剪。若被裁剪,会破坏板和路径的映射关系,则不能继续其他操作
|
|
|
|
|
|
|
|
if (this.objectId || (this.IsEmbedEntity && this.ParentEntity.objectId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const frontPath = ArcBoardBuild.OffsetPolyline(sweepPath, -this.thickness); // 正面path
|
|
|
|
|
|
|
|
const backPath = ArcBoardBuild.OffsetPolyline(frontPath, this.thickness); // 背面path
|
|
|
|
|
|
|
|
if (!equaln(backPath.Length, sweepPath.Length, 1e-3))
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
sweepPath = ArcBoardBuild.OffsetPolyline(path, this.thickness);
|
|
|
|
|
|
|
|
// 做offset偏移,查看path是否会被裁剪。若被裁剪,会破坏板和路径的映射关系,则不能继续其他操作
|
|
|
|
|
|
|
|
if (this.objectId || (this.IsEmbedEntity && this.ParentEntity.objectId))
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
const frontPath = ArcBoardBuild.OffsetPolyline(sweepPath, -this.thickness);// 正面path
|
|
|
|
|
|
|
|
if (!equaln(frontPath.Length, path.Length, 1e-3))
|
|
|
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
this._SweepPath = sweepPath;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
this._jigSweepPath = path.Clone();
|
|
|
|
|
|
|
|
if (jigSpt)
|
|
|
|
|
|
|
|
MovePath(this._jigSweepPath, jigSpt);// 新路径,但是未进行起始点偏移。方便拖拽时,实时显示当前路径
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 更新圆弧配置
|
|
|
|
|
|
|
|
if (this.objectId || (this.IsEmbedEntity && this.ParentEntity.objectId))
|
|
|
|
|
|
|
|
this.UpdateArcBoardOptionsByPath(arcKeys, this._jigSweepPath);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return path;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
DeferUpdate()
|
|
|
|
DeferUpdate()
|
|
|
|
{
|
|
|
|
{
|
|
|
|
if (this.NeedUpdateFlag & UpdateDraw.Matrix)
|
|
|
|
if (this.NeedUpdateFlag & UpdateDraw.Matrix)
|
|
|
|