Compare commits

...

2 Commits

Author SHA1 Message Date
cc42238333 修复:移除错误的引用 2020-11-12 11:31:42 +08:00
e60b70b2b1 修复:V型刀算法在位封闭图形上错误的问题 2020-11-12 10:50:44 +08:00
3 changed files with 301 additions and 76 deletions

View File

@@ -967,7 +967,7 @@ class UserConfig {
this.SystemConfig = {
maxHightightCount: 15000,
snapSize: 15,
aaType: AAType.FXAA
aaType: AAType.FXAA,
};
this.viewDirType = ViewDirType.XN;
this.useCtrlRotate = true;
@@ -993,6 +993,11 @@ class UserConfig {
};
this.autoLines = false;
this.dimTextHeight = 60;
this.performanceConfig = {
fakersweep: false,
disablerefcut: false,
disablecheckgroove: false,
};
this.configName = "default";
this.configsNames = [];
this.Init();
@@ -1153,6 +1158,9 @@ __decorate([
__decorate([
observable
], UserConfig.prototype, "autoLines", void 0);
__decorate([
observable
], UserConfig.prototype, "performanceConfig", void 0);
const userConfig = new UserConfig();
/**
@@ -6023,6 +6031,38 @@ let Polyline = Polyline_1 = class Polyline extends Curve {
}
return pl;
}
/**首尾相连的曲线直接连接 */
static FastCombine(curves, tolerance = 1e-5) {
if (!curves || curves.length === 0)
return;
let pl = new Polyline_1;
pl.OCS = ComputerCurvesNormalOCS(curves);
let ocsInv = pl.OCSInv;
let lineData = [];
for (let i = 0; i < curves.length; i++) {
let cu = curves[i];
let bul = 0;
if (cu instanceof Arc)
bul = cu.Bul;
lineData.push({
pt: AsVector2(cu.StartPoint.applyMatrix4(ocsInv)),
bul
});
if (i === curves.length - 1) {
lineData.push({
pt: AsVector2(cu.EndPoint.applyMatrix4(ocsInv)),
bul: 0
});
}
}
if (lineData.length > 1) {
let ld = arrayLast(lineData).pt;
if (equalv2(lineData[0].pt, ld, tolerance))
ld.copy(lineData[0].pt);
}
pl.LineData = lineData;
return pl;
}
PtOnCurve(pt) {
for (let i = 0; i < this.EndParam; i++) {
let c = this.GetCurveAtIndex(i);
@@ -9245,6 +9285,15 @@ let Region = Region_1 = class Region extends Entity {
mesh.receiveShadow = true;
return mesh;
}
else if (renderType === RenderType.Print) {
return new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(0));
}
else if (renderType === RenderType.Physical2) {
let mesh = new Mesh(this.MeshGeometry, this.MeshMaterial);
mesh.castShadow = true;
mesh.receiveShadow = true;
return new Object3D().add(new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(this.ColorIndex)), mesh);
}
}
UpdateDrawObject(renderType, obj) {
DisposeThreeObj(obj);
@@ -9262,16 +9311,25 @@ let Region = Region_1 = class Region extends Entity {
mesh.geometry = this.MeshGeometry;
mesh.material = this.MeshMaterial;
}
else if (renderType === RenderType.Physical2) {
let mesh = new Mesh(this.MeshGeometry, this.MeshMaterial);
mesh.castShadow = true;
mesh.receiveShadow = true;
return obj.add(new LineSegments(this.EdgeGeometry, ColorMaterial.GetLineMaterial(this.ColorIndex)), mesh);
}
else if (renderType === RenderType.Print) {
let l = obj;
l.geometry = this.EdgeGeometry;
l.material = ColorMaterial.GetLineMaterial(0);
}
}
/**
* 当实体需要被更新时,更新实体材质
*/
UpdateDrawObjectMaterial(type, obj, material) {
if (type === RenderType.Wireframe) {
for (let l of obj.children) {
let line = l;
line.material = ColorMaterial.GetLineMaterial(this.ColorIndex);
}
if (type === RenderType.Wireframe || type === RenderType.Print) {
let line = obj;
line.material = ColorMaterial.GetLineMaterial(this.ColorIndex);
}
else if (type === RenderType.Conceptual) {
for (let i = 0; i < obj.children.length; i++) {
@@ -14146,7 +14204,8 @@ let CompositeEntity = CompositeEntity_1 = class CompositeEntity extends Entity {
this.Entitys.length = 0;
for (let i = 0; i < count; i++) {
let ent = file.ReadObject();
this.Entitys.push(ent);
if (ent)
this.Entitys.push(ent);
}
}
//对象将自身数据写入到文件.
@@ -14400,7 +14459,7 @@ const DefaultSingleBoardOption = {
};
Object.freeze(DefaultSingleBoardOption);
const DefaultClosingStripOption = {
version: 1,
version: 2,
type: BoardType.Vertical,
name: "收口条",
striptype: StripType.H,
@@ -14408,6 +14467,9 @@ const DefaultClosingStripOption = {
width: 54,
thickness: 18,
frontShrink: 0,
isDrawFuZhu: true,
fzWidth: 80,
fzThickness: 18,
};
Object.freeze(DefaultClosingStripOption);
const DefaultBoardFindOption = {
@@ -15239,8 +15301,7 @@ let Board = Board_1 = class Board extends ExtrudeSolid {
return this._BoardProcessOption;
}
set BoardProcessOption(obj) {
obj.highSealed = obj.highSealed.slice();
Object.assign(this._BoardProcessOption, obj);
Object.assign(this._BoardProcessOption, obj, { [EBoardKeyList.HighSealed]: obj[EBoardKeyList.HighSealed].slice() });
}
get NeedUpdateRelevanceGroove() {
if (super.NeedUpdateRelevanceGroove)
@@ -15516,9 +15577,10 @@ let Board = Board_1 = class Board extends ExtrudeSolid {
}
set ContourCurve(cu) {
if (!this.contourCurve || cu.EndParam !== this.contourCurve.EndParam || !this.BoardProcessOption.drillType) {
let drillTypes = [...userConfig.DrillConfigs.keys(), "不排"];
let defaultType = this._BoardProcessOption.drillType;
if (!defaultType) {
defaultType = userConfig.DrillConfigs.size > 0 ? [...userConfig.DrillConfigs.keys()][0] : "不排";
if (!defaultType || !drillTypes.includes(defaultType)) {
defaultType = drillTypes[0];
this._BoardProcessOption.drillType = defaultType;
}
this._BoardProcessOption.highDrill = Array(cu.EndParam).fill(defaultType);
@@ -15913,6 +15975,7 @@ let ExtrudeHole = class ExtrudeHole extends Hole {
this._contourCurve = new Polyline();
this._knifeRadius = 3;
this.isHole = true;
this.isThrough = false;
}
get KnifeRadius() {
return this._knifeRadius;
@@ -16209,24 +16272,31 @@ let ExtrudeHole = class ExtrudeHole extends Hole {
if (ver > 1) {
this.isHole = file.Read();
}
if (ver > 2)
this.isThrough = file.Read();
this.Update();
}
//对象将自身数据写入到文件.
WriteFile(file) {
super.WriteFile(file);
file.Write(2);
file.Write(3);
file.WriteObject(this._contourCurve);
file.Write(this._knifeRadius);
file.Write(this.isHole);
file.Write(this.isThrough);
}
};
__decorate([
AutoRecord
], ExtrudeHole.prototype, "isHole", void 0);
__decorate([
AutoRecord
], ExtrudeHole.prototype, "isThrough", void 0);
ExtrudeHole = __decorate([
Factory
], ExtrudeHole);
const CanDrawHoleFuzz = 1e-2;
var BoardFaceType;
(function (BoardFaceType) {
BoardFaceType[BoardFaceType["Side"] = 0] = "Side";
@@ -16261,6 +16331,20 @@ function FixIndex$1(index, arr) {
return index;
}
var Intent;
(function (Intent) {
Intent["NONE"] = "none";
Intent["PRIMARY"] = "primary";
Intent["SUCCESS"] = "success";
Intent["WARNING"] = "warning";
Intent["DANGER"] = "danger";
})(Intent || (Intent = {}));
const ToasterInjectFunctions = [];
function Toaster(option) {
for (let f of ToasterInjectFunctions)
f(option);
}
var CylinderHole_1;
var GangDrillType;
(function (GangDrillType) {
@@ -17012,25 +17096,135 @@ let HardwareTopline = class HardwareTopline extends SweepSolid {
let mat = new Matrix4().makeBasis(x, y, z);
mat.setPosition(c.StartPoint);
[cMin, cMax].forEach(p => p.applyMatrix4(mat).setZ(0));
let closePt = c.GetClosestPointTo(cMin, false);
let firstCurve;
if (c instanceof Polyline)
firstCurve = c.GetCurveAtParam(0);
else
firstCurve = c;
let closePt = firstCurve.GetClosestPointTo(cMin, false);
let offset = cMin.distanceTo(closePt);
let dir = GetPointAtCurveDir(this.Path, cMin);
let dir = GetPointAtCurveDir(firstCurve, cMin);
let cus = this.Path.GetOffsetCurves(offset * dir);
let l1 = (_a = cus[0]) !== null && _a !== void 0 ? _a : this.Path;
closePt = c.GetClosestPointTo(cMax, false);
offset = cMax.distanceTo(closePt);
dir = GetPointAtCurveDir(this.Path, cMax);
cus = this.Path.GetOffsetCurves(offset * dir);
let l2 = (_b = cus[0]) !== null && _b !== void 0 ? _b : this.Path;
let l1 = (_a = cus[0]) !== null && _a !== void 0 ? _a : this.Path.Clone();
closePt = firstCurve.GetClosestPointTo(cMax, false);
let offset2 = cMax.distanceTo(closePt);
dir = GetPointAtCurveDir(firstCurve, cMax);
cus = this.Path.GetOffsetCurves(offset2 * dir);
let l2 = (_b = cus[0]) !== null && _b !== void 0 ? _b : this.Path.Clone();
this._ContourWidth = offset + offset2;
return [l1, l2];
}
get MaxPath() {
let [l1, l2] = this.Contours;
return l1.Length > l2.Length ? l1 : l2;
/**
*延伸取最大最小轮廓每段首尾到前面线段,取最长线段作为分段长
*
*/
get Segmentations() {
const [l1, l2] = this.Contours;
if (!(l1 instanceof Polyline))
return [l1];
let cus1 = l1.Explode();
let cus2 = l2.Explode();
[cus1, cus2] = cus1.length < cus2.length ? [cus2, cus1] : [cus1, cus2];
let sgs = [];
const AddSgs = (c1, c2) => {
sgs.push(c1.Length > c2.Length ? c1 : c2);
};
const ExtendCurve = (c, refC, isPre) => {
let pts = c.IntersectWith2(refC, IntersectOption.ExtendBoth).filter(r => {
if (isPre)
return r.thisParam < 0;
else
return r.thisParam > 1;
});
if (isPre) {
pts.sort((r1, r2) => r2.thisParam - r1.thisParam);
if (pts.length > 0 && pts[0].thisParam < 0)
c.Extend(pts[0].thisParam);
}
else {
pts.sort((r1, r2) => r1.thisParam - r2.thisParam);
if (pts.length > 0 && pts[0].thisParam > 1)
c.Extend(pts[0].thisParam);
}
};
const IsNoRelativeCurve = (c1, c2) => {
if ((c1 instanceof Line) !== (c2 instanceof Line))
return true;
let midPt = c1.GetPointAtParam(0.5);
let closePt = c2.GetClosestPointTo(midPt, false);
return !closePt || !equaln(midPt.distanceTo(closePt), this._ContourWidth, 1e-3);
};
const HasRelativeCurveAndChange = (target, cs, isChange = false) => {
let index = cs.findIndex(c => !IsNoRelativeCurve(c, target));
if (index !== -1) {
if (isChange && l1.IsClose)
cs.unshift(...cs.splice(index));
return true;
}
return false;
};
if (cus1.length !== cus2.length)
arrayRemoveIf(cus2, c => !HasRelativeCurveAndChange(c, cus1));
for (let i = 0; i < cus1.length; i++) {
let c1 = cus1[i];
let c2 = cus2[i];
if (cus1.length !== cus2.length) {
if (IsNoRelativeCurve(c1, c2)) {
sgs.push(c1);
cus1.splice(i, 1);
i--;
continue;
}
}
else {
//第一段验证是否是关联段,不关联重置数组顺序
if (i === 0) {
if (IsNoRelativeCurve(c1, c2)) {
if (!HasRelativeCurveAndChange(c1, cus2, true)) {
console.error("错误");
return cus1;
}
i--;
continue;
}
}
}
let nextC1;
if (l1.IsClose) {
nextC1 = cus1[FixIndex$1(i + 1, cus1.length)];
}
else {
if (i < cus1.length - 1) {
nextC1 = cus1[i + 1];
}
}
if (nextC1) {
let derv = c1.GetFistDeriv(0).normalize();
let derv2 = nextC1.GetFistDeriv(0).normalize();
if (isPerpendicularityTo(derv, derv2) && isPerpendicularityTo(derv, c1.StartPoint.sub(c2.StartPoint).normalize())) {
AddSgs(c1, c2);
continue;
}
}
let nextDerv1 = c1.GetFistDeriv(1).normalize();
let nextDerv2 = c2.GetFistDeriv(1).normalize();
let preDerv1 = c1.GetFistDeriv(0).normalize();
let preDerv2 = c2.GetFistDeriv(0).normalize();
[nextDerv1, nextDerv2, preDerv1, preDerv2].forEach(d => rotatePoint(d, Math.PI / 2));
let preRefLine1 = new Line(c1.StartPoint, c1.StartPoint.add(preDerv1));
let preRefLine2 = new Line(c2.StartPoint, c2.StartPoint.add(preDerv2));
let nextRefLine1 = new Line(c1.EndPoint, c1.EndPoint.add(nextDerv1));
let nextRefLine2 = new Line(c2.EndPoint, c2.EndPoint.add(nextDerv2));
ExtendCurve(c1, nextRefLine2, false);
ExtendCurve(c2, nextRefLine1, false);
ExtendCurve(c1, preRefLine2, true);
ExtendCurve(c2, preRefLine1, true);
AddSgs(c1, c2);
}
return sgs;
}
get MaxLength() {
let [l1, l2] = this.Contours;
return Math.max(l1.Length, l2.Length);
return this.Segmentations.reduce((len, c) => len + c.Length, 0);
}
set ContourRotation(ro) {
if (ro === this._contourRotation)
@@ -17097,34 +17291,20 @@ HardwareTopline = __decorate([
Factory
], HardwareTopline);
var Intent;
(function (Intent) {
Intent["NONE"] = "none";
Intent["PRIMARY"] = "primary";
Intent["SUCCESS"] = "success";
Intent["WARNING"] = "warning";
Intent["DANGER"] = "danger";
})(Intent || (Intent = {}));
const ToasterInjectFunctions = [];
function Toaster(option) {
for (let f of ToasterInjectFunctions)
f(option);
}
class LookOverBoardInfosTool {
constructor() {
this.drillTypeMap = new Map();
this.sealMap = new Map();
this.boardMap = new Map();
}
GetCount(brs) {
GetCount(brs, options = null) {
let drillCount = [];
let sealCount = [];
let hardwareCount = [];
let areaCount = [];
this.drillTypeMap.clear();
this.sealMap.clear();
this.Update(brs);
this.Update(brs, options);
if (this.drillTypeMap.size > 0)
for (let [k, v] of this.drillTypeMap) {
if (v[0] instanceof Hole)
@@ -17141,7 +17321,7 @@ class LookOverBoardInfosTool {
hardwareCount.sort((h1, h2) => h1.name.localeCompare(h2.name));
//加入封边信息
for (let [k, v] of this.sealMap) {
sealCount.push({ name: k.toString() + "mm封边条", count: v / 1000, unit: "米" });
sealCount.push({ name: k, count: v / 1000, unit: "米" });
}
for (let [k, bs] of this.boardMap) {
areaCount.push({
@@ -17153,7 +17333,7 @@ class LookOverBoardInfosTool {
return { drillCount, hardwareCount, sealCount, areaCount };
}
;
Update(ens) {
Update(ens, options = null) {
var _a, _b, _c;
//计算排钻个数
const addDrillToMap = (spiteName, d) => {
@@ -17230,16 +17410,21 @@ class LookOverBoardInfosTool {
addDrillToMap(`${name},${unit},${factory},${this.ParseSpec(metal, spec)},${model},${brand}`, metal);
}
}
//封边 目前仅厚度,长度两个参数
//封边
let sealData = Production.GetBoardSealingData(b);
let color = b.BoardProcessOption[EBoardKeyList.Color];
for (let data of sealData) {
if (equaln(0, data.size))
continue;
let len = this.sealMap.get(data.size);
let k = `${data.size}-${FixedNotZero(b.Thickness, 2)}-${color}`;
if (options) {
k += options.sealGruopKey(b);
}
let len = this.sealMap.get(k);
if (!len)
this.sealMap.set(data.size, data.length);
this.sealMap.set(k, data.length);
else
this.sealMap.set(data.size, len += data.length);
this.sealMap.set(k, len += data.length);
}
}
}
@@ -17265,8 +17450,7 @@ class LookOverBoardInfosTool {
let addLen = v[0].HardwareOption.addLen;
for (let d of v) {
let e = d;
let path = e.MaxPath;
let cus = path instanceof Polyline ? path.Explode() : [path];
let cus = e.Segmentations;
for (let cu of cus) {
let len = parseFloat(FixedNotZero(cu.Length, 2));
if (map.has(len)) {
@@ -17519,7 +17703,8 @@ var Production;
let len = 2 * Math.PI * cu.Radius / 4;
for (let i = 0; i < splitCount; i++) {
let arcLen = i !== splitCount - 1 ? len : cu.Length - (splitCount - 1) * len;
sealData.push(Object.assign({}, data, { length: arcLen }));
if (!equaln(arcLen, 0))
sealData.push(Object.assign({}, data, { length: arcLen }));
}
}
else if (cu instanceof Circle) {
@@ -17633,8 +17818,8 @@ var Production;
}
let cus = con.Explode();
MergeCurvelist(cus);
let pl = Polyline.Combine(cus, LINK_FUZZ);
if (isSplite && pl.Area2 < 0)
let pl = Polyline.FastCombine(cus, LINK_FUZZ);
if (pl && isSplite && pl.Area2 < 0)
pl.Reverse();
return pl;
}
@@ -17644,6 +17829,7 @@ var Production;
for (let b of bs) {
if (b.__OriginalEnt__) {
b.BoardProcessOption = en.BoardProcessOption;
b.ProcessingGroupList = en.ProcessingGroupList;
for (let [k, ds] of en.DrillList)
b.AppendDrillList(k, ds);
b.AppendNails(en.LayerNails);
@@ -17829,7 +18015,7 @@ var Production;
}
}
else {
if (isParallelTo(d.Normal, br.Normal)) {
if (isParallelTo(d.Normal, br.Normal, CanDrawHoleFuzz)) {
if (position.x <= 0 || position.x >= br.Width || position.y <= 0 || position.y >= br.Height)
return;
position.sub(offsetTanslation);
@@ -17868,7 +18054,7 @@ var Production;
let depth = z0 < 1e-2 ? z1 : br.Thickness - z0;
if (depth > 1e-2)
data.frontBackHoles.push({
type: GangDrillType.Pxl,
type: d.isThrough ? GangDrillType.TK : GangDrillType.Pxl,
position: z0 < 1e-6 ? p : p.setZ(br.Thickness),
radius: cir.Radius,
depth,
@@ -17975,8 +18161,7 @@ var Production;
let datas = [];
let map = new Map();
let addLen = en.HardwareOption.addLen;
let path = en.MaxPath;
let cus = path instanceof Polyline ? path.Explode() : [path];
let cus = en.Segmentations;
let size = en.BoundingBoxInOCS.getSize(new Vector3);
for (let cu of cus) {
let len = parseFloat(FixedNotZero(cu.Length, 2));
@@ -18036,6 +18221,13 @@ var Production;
return sizeData;
}
Production.GetCabSize = GetCabSize;
function Data2Polyline(data, isClose = true) {
let pl = new Polyline(data.pts.map((p, i) => ({ pt: new Vector2(p.x, p.y), bul: data.buls[i] })));
if (isClose)
pl.CloseMark = true;
return pl;
}
Production.Data2Polyline = Data2Polyline;
})(Production || (Production = {}));
/**
@@ -18124,7 +18316,6 @@ function ParagraphCulist(cus) {
function CalcEdgeSealing(cus) {
if (cus.length <= 1)
return;
let oldLine;
let firstLine = cus[0].Clone();
for (let i = 0; i < cus.length; i++) {
let frontLine = cus[i];
@@ -18132,12 +18323,27 @@ function CalcEdgeSealing(cus) {
let laterLine = cus[laterIndex];
if (!frontLine || !laterLine) {
alert("获取封边错误,请提供图纸给相关人员");
return;
return false;
}
let dist = frontLine.EndPoint.distanceToSquared(laterLine.StartPoint);
if (dist < LINK_FUZZ ** 2)
if (dist < LINK_FUZZ ** 2) {
if (frontLine instanceof Line && laterLine instanceof Line) {
if (frontLine.PtOnCurve(laterLine.EndPoint)) {
cus.splice(laterIndex, 1);
if (laterIndex === 0)
firstLine = cus[0].Clone();
i -= 2;
}
else if (laterLine.PtOnCurve(frontLine.StartPoint)) {
cus.splice(i, 1);
i -= 2;
if (i < -1)
i = -1;
}
}
continue;
let refLine = oldLine !== null && oldLine !== void 0 ? oldLine : frontLine;
}
let refLine = frontLine;
let refLine2 = i === cus.length - 1 ? firstLine : laterLine;
let iPts = refLine.IntersectWith(refLine2, IntersectOption.ExtendBoth);
let tPts = iPts.filter(p => refLine.PtOnCurve(p)
@@ -18145,10 +18351,10 @@ function CalcEdgeSealing(cus) {
let iPt = SelectNearP(tPts.length > 0 ? tPts : iPts, frontLine.EndPoint);
if (!iPt) {
alert("获取封边错误,请提供图纸给相关人员");
return;
return false;
}
let par = frontLine.GetParamAtPoint(iPt);
if (par < 0) {
if (par < 1e-6) {
cus.splice(i, 1);
i -= 2;
if (i < -1)
@@ -18156,15 +18362,22 @@ function CalcEdgeSealing(cus) {
}
else
frontLine.EndPoint = iPt;
oldLine = equalv3(iPt, laterLine.EndPoint) ? laterLine.Clone() : null;
par = laterLine.GetParamAtPoint(iPt);
if (par > 1) {
if (par > 1 - 1e-6) {
cus.splice(laterIndex, 1);
i -= 1;
if (laterIndex === 0) {
firstLine = cus[0].Clone();
i -= 2;
}
else
i--;
if (i < -1)
i = -1;
}
else
laterLine.StartPoint = iPt;
}
return true;
}
function GetBoardHighSeal(br, sealcus) {
let highSeals = br.BoardProcessOption.highSealed.slice();
@@ -18212,6 +18425,14 @@ function GetBoardSealingCurves(br, isOffset = false) {
return cu.Explode();
let cus = [];
cu = Production.GetSpliteOutline(br, false);
if (!cu) {
Toaster({
message: "获取封边错误",
timeout: 3000,
intent: Intent.DANGER
});
return [];
}
if (isOffset) {
let dir = Math.sign(cu.Area2);
let newCu = cu.GetOffsetCurves(-1 * dir)[0];
@@ -18267,9 +18488,10 @@ function GetSealedBoardContour(br, hasSealing) {
}
if (offsetCus.length === 1 && offsetCus[0] instanceof Circle)
return offsetCus[0];
CalcEdgeSealing(offsetCus);
let pl = Polyline.Combine(offsetCus, LINK_FUZZ);
if (dir < 0)
if (!CalcEdgeSealing(offsetCus))
return;
let pl = Polyline.FastCombine(offsetCus, LINK_FUZZ);
if (pl && dir < 0)
pl.Reverse();
return pl;
}
@@ -18568,7 +18790,7 @@ class FeedingToolPath extends Singleton {
//若最外轮廓内偏移一个刀半径的曲线 和最内轮廓相交或者被包含,则去掉.且不与洞曲线相等
if (isOut) {
let outlineOffsetCus = outline.GetOffsetCurves(dir * knifRadius).filter(c => c.IsClose);
let outlineCus = GetOffsetCurves(outline, dir * knifRadius);
let outlineCus = GetOffsetCurves(outline, dir * knifRadius).filter(c => c.IsClose);
let ho = holeOffsetCus[i];
let maxArea = Math.max(...(outlineOffsetCus.map(c => c.Area)));
for (let j = 0; j < outlineOffsetCus.length; j++) {
@@ -18989,6 +19211,7 @@ function VKnifToolPath(polyline, feedingDepth, knifAngle) {
arrayRemoveIf(cus, c => c.Length < 0.01);
let offsetx = [x, -x];
let ptsbul = [];
let isClose = polyline.IsClose;
for (let i = 0; i < cus.length; i++) {
let nextIndex = FixIndex(i + 1, cus.length);
let c1 = cus[i];
@@ -19005,6 +19228,11 @@ function VKnifToolPath(polyline, feedingDepth, knifAngle) {
//圆弧与直线相切,此时不要提刀
if (isParallelTo(c1.GetFistDeriv(0), c2.GetFistDeriv(0)))
continue;
if (!isClose && i === cus.length - 1) //最后一条
{
ptsbul.push({ pt: c1.EndPoint, bul: 0 });
break;
}
//提刀
for (let x of offsetx) {
let co1 = c1.GetOffsetCurves(x)[0];
@@ -19021,13 +19249,10 @@ function VKnifToolPath(polyline, feedingDepth, knifAngle) {
ptsbul.push({ pt: ipts[0].setZ(feedingDepth), bul: 0 });
}
}
if (polyline.IsClose) {
if (isClose) {
//第一刀
ptsbul.unshift(ptsbul[ptsbul.length - 1]); //, ptsbul[ptsbul.length - 2]
}
else {
ptsbul.pop();
}
return ptsbul;
}

File diff suppressed because one or more lines are too long

View File

@@ -1,6 +1,6 @@
{
"name": "cadapi",
"version": "0.0.12",
"version": "0.0.13",
"description": "",
"main": "api.esm.js",
"module": "api.esm.js",