!2508 新增:多段偏移联接类型添加切角

pull/2512/MERGE
黄诗津 10 months ago committed by ChenX
parent 4060473721
commit 66bdf07aac

@ -0,0 +1,23 @@
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import { PolylineJoinType } from "../../src/GraphicsSystem/OffsetPolyline";
import { LoadCurvesFromFileData } from "../Utils/LoadEntity.util";
import "../Utils/jest.util";
test('走刀 补直线', () =>
{
/**
* ,线,
*/
let d =
{ "file": [1, "Polyline", 10, 2, 154, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2601.0945127774107, 949.9743923671341, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, 2, 18, [4.547473508864641e-13, 1.1368683772161603e-13], 0, [-120.2931727439086, 22.053748336383364], 0, [-120.2931727439086, -166.85479437718436], 0, [-244.3936752564714, -190.2960004073351], 0, [-459.50121294491373, -543.2929853319582], 0, [-227.84694158812954, -517.0939903570838], -0.40210168311676253, [-316.096187819287, -701.8658496535651], 0, [-142.35548430169774, -701.8658496535662], 0, [-309.2017154574901, -868.7120808093316], 0, [-139.59769535697387, -914.2155983972847], 0, [257.5239126832266, -967.9924828193951], 0, [395.41335991940787, -592.9331863369833], 0, [613.2786865525736, -592.9331863369833], 0, [391.2766765023225, -256.48293508070196], 0, [376.1088373063426, -68.95328683949595], 0, [269.6684368006304, -49.43921341344867], -0.5459751344667229, [141.84056613947723, 1.061209382390416], -0.6541961494111228, [0, 0], 0, false], "basePt": { "x": 2141.593299832497, "y": -18.01809045226105, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] };
let pl = LoadCurvesFromFileData(d)[0] as Polyline;
for (let dist of [3])
{
let cus = pl.GetFeedingToolPath(dist, 9 * 2.1, PolylineJoinType.Square);
expect(cus.length).toMatchSnapshot();
for (let c of cus)
expect(c.Length).toMatchNumberSnapshot();
}
});

@ -10,6 +10,7 @@ import { Command } from '../Editor/CommandMachine';
import { JigUtils } from '../Editor/JigUtils';
import { PromptStatus } from '../Editor/PromptResult';
import { isParallelTo } from '../Geometry/GeUtils';
import { PolylineJoinType } from '../GraphicsSystem/OffsetPolyline';
const OffsetKey = "offset";
@ -265,33 +266,52 @@ export class Command_DynOffsetToolPath
let pl = enRes.Entity as Polyline;
let basePoint: Vector3 = new Vector3();
let dir: number = 0;
let distRes = await app.Editor.GetDistance(
{
Msg: "指定通过点或输入偏移距离:",
BasePoint: basePoint,
CalcDistance: (baseP, p: Vector3) =>
{
basePoint.copy(pl.GetClosestPointTo(p, false));
dir = GetPointAtCurveDir(pl, p);
return p.distanceTo(basePoint) * dir;
},
Callback: (dis: number) =>
{
JigUtils.Destroy();
pl.GetFeedingToolPath(dis).forEach(c => JigUtils.Draw(c));
}
});
let joinType = PolylineJoinType.Round;
if (distRes.Status === PromptStatus.OK)
while (true)
{
let offsetDist = distRes.Distance;
if (dir !== Math.sign(offsetDist))
offsetDist = -offsetDist;
let dir: number = 0;
let distRes = await app.Editor.GetDistance(
{
Msg: `当前衔接类型(${joinType === PolylineJoinType.Round ? "圆边" : "切边"}),指定通过点或输入偏移距离:`,
KeyWordList: [joinType === PolylineJoinType.Round ? { msg: "切边", key: "S" } : { msg: "圆边", key: "R" }],
BasePoint: basePoint,
CalcDistance: (baseP, p: Vector3) =>
{
basePoint.copy(pl.GetClosestPointTo(p, false));
dir = GetPointAtCurveDir(pl, p);
return p.distanceTo(basePoint) * dir;
},
Callback: (dis: number) =>
{
JigUtils.Destroy();
pl.GetFeedingToolPath(dis, (dis ** 2) * 2.1, joinType).forEach(c => JigUtils.Draw(c));
}
});
let pls = pl.GetFeedingToolPath(offsetDist);
for (let pl of pls)
app.Database.ModelSpace.Append(pl);
if (distRes.StringResult === "S")
{
joinType = PolylineJoinType.Square;
}
else if (distRes.StringResult === "R")
{
joinType = PolylineJoinType.Round;
}
else if (distRes.Status === PromptStatus.OK)
{
let offsetDist = distRes.Distance;
if (dir !== Math.sign(offsetDist))
offsetDist = -offsetDist;
let pls = pl.GetFeedingToolPath(offsetDist, (offsetDist ** 2) * 2.1, joinType);
for (let pl of pls)
app.Database.ModelSpace.Append(pl);
break;
}
else
{
break;
}
}
}
}

@ -3,6 +3,7 @@ import { Curve } from "../DatabaseServices/Entity/Curve";
import { Polyline } from "../DatabaseServices/Entity/Polyline";
import { Command } from "../Editor/CommandMachine";
import { PromptStatus } from "../Editor/PromptResult";
import { PolylineJoinType } from "../GraphicsSystem/OffsetPolyline";
import { TestDraw } from "./test/TestUtil";
//无限内偏移
@ -15,21 +16,45 @@ export class OffsetX implements Command
if (ssRes.Status != PromptStatus.OK) return;
let pl = ssRes.Entity as Polyline;
let disRes = await app.Editor.GetDistance({
Msg: "指定偏移距离:",
KeyWordList: [{ msg: "通过", key: "T" }],
Default: this.offsetDis
});
let joinType = PolylineJoinType.Round;
let offsetDis: number;
let offsetDis = Math.abs(disRes.Distance);
TestDraw(pl.GetFeedingToolPath(offsetDis * Math.sign(pl.Area2)), 3);//外偏移
while (true)
{
let disRes = await app.Editor.GetDistance({
Msg: `当前衔接类型(${joinType === PolylineJoinType.Round ? "圆边" : "切边"}),指定偏移距离:`,
KeyWordList: [{ msg: "通过", key: "T" }, joinType === PolylineJoinType.Round ? { msg: "切边", key: "S" } : { msg: "圆边", key: "R" }],
Default: this.offsetDis
});
if (disRes.StringResult === "S")
{
joinType = PolylineJoinType.Square;
}
else if (disRes.StringResult === "R")
{
joinType = PolylineJoinType.Round;
}
else if (disRes.Status === PromptStatus.OK)
{
offsetDis = Math.abs(disRes.Distance);
break;
}
else
{
return;
}
}
const offsetDist = offsetDis * Math.sign(pl.Area2);
TestDraw(pl.GetFeedingToolPath(offsetDist, (offsetDist ** 2) * 2.1, joinType), 3);//外偏移}
let offsetQueue: Curve[] = [pl];
while (offsetQueue.length > 0)
{
let pl = offsetQueue.pop() as Polyline;
let offsets = pl.GetFeedingToolPath(offsetDis * -Math.sign(pl.Area2));
const offsetDist = offsetDis * -Math.sign(pl.Area2);
let offsets = pl.GetFeedingToolPath(offsetDist, (offsetDist ** 2) * 2.1, joinType);
for (let c of offsets)
{
if (c.IsClose)

@ -9,7 +9,7 @@ import { Box3Ext } from '../../Geometry/Box';
import { CreatePolylinePath } from '../../Geometry/CreatePolylinePath';
import { AsVector2, AsVector3, MatrixIsIdentityCS, equaln, equalv2, equalv3 } from '../../Geometry/GeUtils';
import { IntersectOption, IntersectPolylineAndCurve } from '../../GraphicsSystem/IntersectWith';
import { OffsetPolyline } from '../../GraphicsSystem/OffsetPolyline';
import { OffsetPolyline, PolylineJoinType } from '../../GraphicsSystem/OffsetPolyline';
import { Factory } from '../CADFactory';
import { CADFiler } from '../CADFiler';
import { IsPointInPolyLine } from '../PointInPolyline';
@ -600,17 +600,23 @@ export class Polyline extends Curve
{
if (equaln(dist, 0)) return 0;
let cus = this.Explode();
for (let i = 0; i < cus.length; i++)
let cus: (Line | Arc)[] = [];
for (let i = 0; i < this.EndParam; i++)
{
let cu = cus[i];
let cu = this.GetCurveAtIndex(i);
let len = cu.Length;
if (len < 1e-6) continue;
cus.push(cu);
if (dist <= len)
return i + cu.GetParamAtDist(dist);
else if (equaln(dist, len, 1e-8))
return i + 1;
dist -= len;
}
if (!this._ClosedMark)
return cus.length + cus[cus.length - 1].GetParamAtDist(dist);
@ -1236,10 +1242,10 @@ export class Polyline extends Curve
cu.ColorIndex = this.ColorIndex;
return curves;
}
GetFeedingToolPath(offsetDist: number, offsetDistSq = (offsetDist ** 2) * 2.1): Polyline[]
GetFeedingToolPath(offsetDist: number, offsetDistSq = (offsetDist ** 2) * 2.1, joinType: PolylineJoinType = PolylineJoinType.Round): Polyline[]
{
if (equaln(offsetDist, 0)) return [];
let polyOffestUtil = new OffsetPolyline(this, offsetDist, true, offsetDistSq);
let polyOffestUtil = new OffsetPolyline(this, offsetDist, true, offsetDistSq, joinType);
return polyOffestUtil.Do();
}
/**

@ -130,6 +130,12 @@ export class CurveTreeNode
}
}
export enum PolylineJoinType
{
Square = 0,
Round = 1,
}
export class OffsetPolyline
{
//多段线信息
@ -158,8 +164,17 @@ export class OffsetPolyline
_IsTopoOffset = false;//局部偏移,允许特殊延伸,参考测试用例
/**
*
* @param _Polyline
* @param _OffsetDist
* @param [_ToolPath=false] (,(线))
* @param [_OffsetDistSq=(_OffsetDist ** 2) * 2.1]
* @param [JoinType=PolylineJoinType.Round] ,,线
*/
constructor(public _Polyline: Polyline, public _OffsetDist: number, public _ToolPath = false,
private _OffsetDistSq = (_OffsetDist ** 2) * 2.1//对直角走刀不进行圆弧过度
private _OffsetDistSq = (_OffsetDist ** 2) * 2.1,//对直角走刀不进行圆弧过度
private JoinType = PolylineJoinType.Round //仅在走刀路径时生效
)
{
}
@ -297,7 +312,11 @@ export class OffsetPolyline
let distSq = iPts[0].distanceToSquared(refP);
if (this._ToolPath && distSq > this._OffsetDistSq)
{
curveResNow.paddingCurve = [this.CreateArc(refP, sp, ep)];
if (this.JoinType === PolylineJoinType.Round)
curveResNow.paddingCurve = [this.CreateArc(refP, sp, ep)];
else
curveResNow.paddingCurve = [this.CreateSquare(refP, curveResNow, curveResNext, code)];//补直线
this._TrimCircleContours.push(this._Circles[curveResNext.index]);
}
else
@ -307,7 +326,7 @@ export class OffsetPolyline
// curveResNow.paddingCurve = [new Line(sp, ep)];
}
}
else
else//直线和圆弧 圆弧和圆弧
{
let refP = this._Vertexs[curveResNext.index];
@ -394,7 +413,14 @@ export class OffsetPolyline
curveResNow.paddingCurve = [this.CreateArc(refP, sp, ep)];//补圆弧
}
else
curveResNow.paddingCurve = [this.CreateArc(refP, sp, ep)];//补圆弧
{
if (this.JoinType === PolylineJoinType.Round)
curveResNow.paddingCurve = [this.CreateArc(refP, sp, ep)];//补圆弧
else
{
curveResNow.paddingCurve = [this.CreateSquare(refP, curveResNow, curveResNext, code)];//补直线
}
}
let circle = this._Circles[curveResNext.index];
if (circle) this._TrimCircleContours.push(circle);//因为局部偏移可能未提供圆
@ -938,6 +964,30 @@ export class OffsetPolyline
let arc = new Arc(center, Math.abs(this._OffsetDist), sa, ea, this._OffsetDist < 0);
return arc;
}
protected CreateSquare(center: Vector3, curveNow: IOffsetResult, curveNext: IOffsetResult, entTypeCode: number)
{
const arc = this.CreateArc(center, curveNow.curve.EndPoint, curveNext.curve.StartPoint);
const centerPoint = arc.GetPointAtParam(0.5);
const tangentLine = new Line(centerPoint, arc.GetFirstDeriv(0.5).add(centerPoint)); //切线
let ep: Vector3, sp: Vector3;
if (entTypeCode === 1)
{
ep = tangentLine.IntersectWith(curveNow.curve, IntersectOption.ExtendBoth)[0]; //第一条线新的终点坐标
sp = centerPoint.multiplyScalar(2).sub(ep);
}
else// if (entTypeCode === 0)//全圆弧 直线和圆弧
{
ep = SelectNearP(tangentLine.IntersectWith(curveNow.curve, IntersectOption.ExtendBoth), center); //第一条线新的终点坐标
sp = SelectNearP(tangentLine.IntersectWith(curveNext.curve, IntersectOption.ExtendBoth), center);
}
curveNow.ep = ep;
curveNext.sp = sp;
return new Line(ep, sp);
}
}
function EntityEncode(c: Curve)

Loading…
Cancel
Save