From f95e0ff9fa026e5d1c666b46726273534f777ef2 Mon Sep 17 00:00:00 2001 From: ChenX Date: Fri, 19 Apr 2019 09:22:23 +0800 Subject: [PATCH] !287 fixed #IVDHC ##IVEOQ Merge pull request !287 from ZoeLeeFZ/fixTestM --- .../FeedingToolPath/FeedingToolPath.test.ts | 21 ++++++- .../FeedingToolPath.test.ts.snap | 58 ++++++++++--------- src/Add-on/PasteClip.ts | 22 ++++--- src/DatabaseServices/Text/TextArea.ts | 1 - src/GraphicsSystem/OffsetPolyline.ts | 17 ++++-- .../ToolPath/FeedingToolPath.ts | 57 ++++++++++++------ 6 files changed, 113 insertions(+), 63 deletions(-) diff --git a/__test__/FeedingToolPath/FeedingToolPath.test.ts b/__test__/FeedingToolPath/FeedingToolPath.test.ts index 44055a046..dabcd8a8e 100644 --- a/__test__/FeedingToolPath/FeedingToolPath.test.ts +++ b/__test__/FeedingToolPath/FeedingToolPath.test.ts @@ -12,8 +12,10 @@ function testPathCount(br: Board, count?: number) let cus = feedUtil.CalcPath(br); if (count !== undefined) expect(cus.length).toBe(count); - expect(cus.length).toBeGreaterThan(2); - expect(cus.length - 2 - holeCount).toMatchSnapshot("走刀数量"); + else + expect(cus.length).toBeGreaterThan(2); + let pathCount = cus.length - 1 - holeCount - br.BoardModeling.length; + expect(pathCount < 0 ? 0 : pathCount).toMatchSnapshot("走刀数量"); for (let cu of cus) { expect(cu.Length).toMatchSnapshot("曲线长度"); @@ -100,3 +102,18 @@ test("复杂造型测试", () => brs = LoadBoardsFromFileData(data); testPathCount(brs[0]); }) + +test("造型的外框和内框厚度小于刀半径厚度", () => +{ + let data = + [1, "Board", 3, 2, 101, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 26851.321807232103, -1144.6658743078003, 0, 1], 2, 1200, 600, 18, true, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 1, 2, 416.58619999999996, 325.1405, 5, true, "Polyline", 3, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1187.5114150409554, -619.5823942857144, 0, 1], 2, 4, [1187.5114150409554, 619.5823942857144], 0, [1512.6519150409554, 619.5823942857144], 0, [1512.6519150409554, 1036.1685942857143], 0, [1187.5114150409554, 1036.1685942857143], 0, true, 1, 2, 408.58619999999996, 317.1405, 5, true, "Polyline", 3, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1191.5114150409554, -623.5823942857144, 0, 1], 2, 4, [1508.6519150409554, 1032.1685942857143], 0, [1191.5114150409554, 1032.1685942857143], 0, [1191.5114150409554, 623.5823942857144], 0, [1508.6519150409554, 623.5823942857144], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 26864.321807232103, -1017.7520587975966, 453.37831265306136, 1], 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 26864.321807232103, -1021.7520587975966, 449.37831265306136, 1], 3, 0, 0, 0, 2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -537.1188495066017, 139.8723180005327, 0, 1], 1, "左侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\",\"highDrill\":[]}", 0, 0] + let brs = LoadBoardsFromFileData(data); + testPathCount(brs[0], 1); +}) +test("造型的外框和内框厚度等于刀直径", () => +{ + let data = + [1, "Board", 3, 2, 118, false, 1, 11, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 25702.129700607577, -1144.6658743078003, 0, 1], 2, 1200, 600, 18, true, "Polyline", 3, 2, 0, false, 0, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 2, 4, [0, 0], 0, [600, 0], 0, [600, 1200], 0, [0, 1200], 0, true, 1, 2, 416.58619999999996, 325.1405, 5, true, "Polyline", 3, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1187.5114150409554, -619.5823942857144, 0, 1], 2, 4, [1187.5114150409554, 619.5823942857144], 0, [1512.6519150409554, 619.5823942857144], 0, [1512.6519150409554, 1036.1685942857143], 0, [1187.5114150409554, 1036.1685942857143], 0, true, 1, 2, 404.58619999999996, 313.1405, 5, true, "Polyline", 3, 2, 0, false, 0, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1193.5114150409554, -625.5823942857144, 0, 1], 2, 4, [1506.6519150409554, 1030.1685942857143], 0, [1193.5114150409554, 1030.1685942857143], 0, [1193.5114150409554, 625.5823942857144], 0, [1506.6519150409554, 625.5823942857144], 0, true, 0, 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 25715.129700607577, -1015.7520587975966, 455.37831265306136, 1], 3, 0, 0, 0, [0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 25715.129700607577, -1021.7520587975966, 449.37831265306136, 1], 3, 0, 0, 0, 2, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1686.3109561311285, 139.8723180005327, 0, 1], 1, "左侧板", "{\"roomName\":\"\",\"cabinetName\":\"\",\"boardName\":\"\",\"material\":\"\",\"color\":\"\",\"lines\":0,\"bigHoleDir\":0,\"drillType\":\"three\",\"composingFace\":2,\"highSealed\":[],\"sealedUp\":\"1\",\"sealedDown\":\"1\",\"sealedLeft\":\"1\",\"sealedRight\":\"1\",\"spliteHeight\":\"\",\"spliteWidth\":\"\",\"spliteThickness\":\"\",\"highDrill\":[\"three\",\"three\",\"three\",\"three\",\"three\",\"three\"]}", 0, 0] + let brs = LoadBoardsFromFileData(data); + testPathCount(brs[0], 4); +}) diff --git a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap index 15428c0e1..2a6134dc7 100644 --- a/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap +++ b/__test__/FeedingToolPath/__snapshots__/FeedingToolPath.test.ts.snap @@ -48,7 +48,7 @@ exports[`复杂极限刀半径: 曲线长度 5`] = `2927.3167299028455`; exports[`复杂极限刀半径: 曲线长度 6`] = `3278.917934988776`; -exports[`复杂极限刀半径: 走刀数量 1`] = `4`; +exports[`复杂极限刀半径: 走刀数量 1`] = `3`; exports[`复杂造型测试: 曲线长度 1`] = `2402.511185283596`; @@ -102,51 +102,43 @@ exports[`复杂造型测试: 曲线长度 25`] = `162.171881370416`; exports[`复杂造型测试: 曲线长度 26`] = `3600`; -exports[`复杂造型测试: 曲线长度 27`] = `103756.1096358091`; +exports[`复杂造型测试: 曲线长度 27`] = `106446.82051694988`; -exports[`复杂造型测试: 曲线长度 28`] = `487.19933816470575`; +exports[`复杂造型测试: 曲线长度 28`] = `2581.084814115112`; -exports[`复杂造型测试: 曲线长度 29`] = `2152.7628031484846`; +exports[`复杂造型测试: 曲线长度 29`] = `463.19933816470575`; -exports[`复杂造型测试: 曲线长度 30`] = `2581.084814115112`; +exports[`复杂造型测试: 曲线长度 30`] = `5545.665343214347`; -exports[`复杂造型测试: 曲线长度 31`] = `463.19933816470575`; +exports[`复杂造型测试: 曲线长度 31`] = `713.891109728082`; -exports[`复杂造型测试: 曲线长度 32`] = `5545.665343214347`; +exports[`复杂造型测试: 走刀数量 1`] = `12`; -exports[`复杂造型测试: 曲线长度 33`] = `713.891109728082`; - -exports[`复杂造型测试: 走刀数量 1`] = `23`; - -exports[`复杂造型测试: 走刀数量 2`] = `5`; +exports[`复杂造型测试: 走刀数量 2`] = `2`; exports[`带孔造型板件: 曲线长度 1`] = `3600`; exports[`带孔造型板件: 曲线长度 2`] = `53389.1518227565`; -exports[`带孔造型板件: 曲线长度 3`] = `1233.6929369796912`; - -exports[`带孔造型板件: 曲线长度 4`] = `4667.086663355046`; +exports[`带孔造型板件: 曲线长度 3`] = `4667.086663355046`; -exports[`带孔造型板件: 曲线长度 5`] = `2195.9741153279983`; +exports[`带孔造型板件: 曲线长度 4`] = `2195.9741153279983`; -exports[`带孔造型板件: 曲线长度 6`] = `1209.6929369796912`; +exports[`带孔造型板件: 曲线长度 5`] = `1209.6929369796912`; -exports[`带孔造型板件: 曲线长度 7`] = `3600`; +exports[`带孔造型板件: 曲线长度 6`] = `3600`; -exports[`带孔造型板件: 曲线长度 8`] = `53389.1518227565`; +exports[`带孔造型板件: 曲线长度 7`] = `53389.1518227565`; -exports[`带孔造型板件: 曲线长度 9`] = `1233.6929369796912`; +exports[`带孔造型板件: 曲线长度 8`] = `4667.086663355046`; -exports[`带孔造型板件: 曲线长度 10`] = `4667.086663355046`; +exports[`带孔造型板件: 曲线长度 9`] = `2195.9741153279983`; -exports[`带孔造型板件: 曲线长度 11`] = `2195.9741153279983`; +exports[`带孔造型板件: 曲线长度 10`] = `1209.6929369796912`; -exports[`带孔造型板件: 曲线长度 12`] = `1209.6929369796912`; +exports[`带孔造型板件: 走刀数量 1`] = `2`; -exports[`带孔造型板件: 走刀数量 1`] = `3`; - -exports[`带孔造型板件: 走刀数量 2`] = `3`; +exports[`带孔造型板件: 走刀数量 2`] = `2`; exports[`极限刀半径: 曲线长度 1`] = `3600`; @@ -195,3 +187,17 @@ exports[`通孔造型测试: 曲线长度 2`] = `1896.616834159402`; exports[`通孔造型测试: 曲线长度 3`] = `1872.616834159402`; exports[`通孔造型测试: 走刀数量 1`] = `1`; + +exports[`造型的外框和内框厚度小于刀半径厚度: 曲线长度 1`] = `3600`; + +exports[`造型的外框和内框厚度小于刀半径厚度: 走刀数量 1`] = `0`; + +exports[`造型的外框和内框厚度等于刀直径: 曲线长度 1`] = `3600`; + +exports[`造型的外框和内框厚度等于刀直径: 曲线长度 2`] = `1459.4533999999999`; + +exports[`造型的外框和内框厚度等于刀直径: 曲线长度 3`] = `1483.4533999999999`; + +exports[`造型的外框和内框厚度等于刀直径: 曲线长度 4`] = `1435.4533999999999`; + +exports[`造型的外框和内框厚度等于刀直径: 走刀数量 1`] = `1`; diff --git a/src/Add-on/PasteClip.ts b/src/Add-on/PasteClip.ts index 5562e28b2..512bf8248 100644 --- a/src/Add-on/PasteClip.ts +++ b/src/Add-on/PasteClip.ts @@ -1,4 +1,4 @@ -import { Matrix4 } from "three"; +import { Matrix4, Vector3 } from "three"; import { app } from "../ApplicationServices/Application"; import { readClipboardText } from "../Common/Utils"; import { CADFiler } from "../DatabaseServices/CADFiler"; @@ -16,11 +16,10 @@ export class PasteClip let data = JSON.parse(str); if (data) { - let obj = data.file; - let f = new CADFiler(); - f.Data = obj; - let count = f.Read(); + let obj = data.file || data; + let f = new CADFiler(obj); + let count = f.Read(); let ens: Entity[] = []; for (let i = 0; i < count; i++) { @@ -29,25 +28,24 @@ export class PasteClip JigUtils.Draw(en); } - let oldBasePt = data.basePt; + let oldBasePt = data.basePt || new Vector3(); let oldPt = app.m_Editor.m_MouseCtrl.m_CurMousePointWCS; - ens.forEach(en => + for (let en of ens) { let vec = en.Position.sub(oldBasePt); en.Position = oldPt.clone().add(vec); - }); + } let ptRes = await app.m_Editor.GetPoint({ - BasePoint: oldPt, Callback: p => + BasePoint: oldPt, + Callback: p => { let moveMat = new Matrix4(); let moveVec = p.clone().sub(oldPt); moveMat.makeTranslation(moveVec.x, moveVec.y, moveVec.z); - ens.forEach(e => - { + for (let e of ens) e.ApplyMatrix(moveMat); - }) oldPt = p.clone(); } }); diff --git a/src/DatabaseServices/Text/TextArea.ts b/src/DatabaseServices/Text/TextArea.ts index ab94051f8..1efb0e464 100644 --- a/src/DatabaseServices/Text/TextArea.ts +++ b/src/DatabaseServices/Text/TextArea.ts @@ -149,7 +149,6 @@ export class TextArea extends Singleton this.m_AreaContiner.removeChild(el); t.TextString = el.innerText; - this.m_EditoringObject.visible = true; this.EndEditor(); } else diff --git a/src/GraphicsSystem/OffsetPolyline.ts b/src/GraphicsSystem/OffsetPolyline.ts index 679fbbe6f..a8c28ab73 100644 --- a/src/GraphicsSystem/OffsetPolyline.ts +++ b/src/GraphicsSystem/OffsetPolyline.ts @@ -42,6 +42,10 @@ export class PolyOffsetUtil this.m_AbsDist = Math.abs(this.m_OffsetDist); this.m_PtCount = pl.EndParam; } + + /** + * @param [isCalcPath=false] + */ GetOffsetCurves(isCalcPath = false): Curve[] { const originOCS = this.m_Polyline.OCS; @@ -65,12 +69,15 @@ export class PolyOffsetUtil this.optimizeCus(boxCurves); this.linkCurves(); - //如果源线段闭合只保留闭合的部分(理论上可以删除这个判断) - if (!isCalcPath && this.m_Polyline.IsClose) - this.m_RetCurves = this.m_RetCurves.filter(c => c.IsClose); + if (!isCalcPath) + { + //如果源线段闭合只保留闭合的部分(理论上可以删除这个判断) + if (this.m_Polyline.IsClose) + this.m_RetCurves = this.m_RetCurves.filter(c => c.IsClose); - if (!isCalcPath && this.m_Polyline.CloseMark) - this.m_RetCurves.forEach(pl => (pl).CloseMark = true); + if (this.m_Polyline.CloseMark) + this.m_RetCurves.forEach(pl => (pl).CloseMark = true); + } return this.m_RetCurves.map(pl => pl.ApplyMatrix(originOCS)); } diff --git a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts index b6f733e33..eef969528 100644 --- a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts +++ b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts @@ -8,6 +8,7 @@ import { Shape } from "../../DatabaseServices/Shape"; import { ShapeManager } from "../../DatabaseServices/ShapeManager"; import { BoolOpeartionType } from "../BoolOperateUtils"; import { OptimizeToolPath } from "./OptimizeToolPath"; +import { equalCurve } from "../../Common/CurveUtils"; /** *计算走刀工具类 @@ -15,12 +16,12 @@ import { OptimizeToolPath } from "./OptimizeToolPath"; export class FeedingToolPath extends Singleton { /** - *处理形状,内偏移 - * @param {Shape} shape - * @param {number} rad 刀半径/偏移距离 - * @param {boolean} isOut 是否是最外轮廓,如果是,洞需要外偏移一个刀半径,多段线偏移保留不闭合轮廓 + * 处理形状,内偏移 + * @param shape 造型Shape + * @param knifRadius 刀半径/偏移距离 + * @param [isOut=true] 是否是最外轮廓,如果是,洞需要外偏移一个刀半径,多段线偏移保留不闭合轮廓 */ - private HandleShape(shape: Shape, rad: number, isOut = true): Curve[] + private HandleShape(shape: Shape, knifRadius: number, isOut = true): Curve[] { let outline = shape.Outline.Curve.Clone(); @@ -35,7 +36,7 @@ export class FeedingToolPath extends Singleton return h.Clone(); let dir = -this.GetCurveToInDir(h.Curve); - let tmpCus = h.Curve.GetOffsetCurves(rad * dir); + let tmpCus = h.Curve.GetOffsetCurves(knifRadius * dir); return Contour.CreateContour(tmpCus); }); @@ -44,10 +45,10 @@ export class FeedingToolPath extends Singleton while (true) { - offsetDist += rad; + offsetDist += knifRadius; let retCus: Curve[] = []; - if (outline instanceof Polyline && isOut && offsetDist === rad) + if (outline instanceof Polyline && isOut && offsetDist === knifRadius) retCus.push(...outline.GetFeedingToolPath(offsetDist * dir)); else retCus.push(...outline.GetOffsetCurves(offsetDist * dir)); @@ -78,16 +79,42 @@ export class FeedingToolPath extends Singleton for (let s of shapeMg.ShapeList) { s.Outline.Curve.ColorIndex = outline.ColorIndex; - offsetCus.push(...this.HandleShape(s, rad, false)); + offsetCus.push(...this.HandleShape(s, knifRadius, false)); } break; } } - //如果加工洞外圈和最外轮廓相交,则去掉 for (let h of holes) { - if (h.Curve.IntersectWith(outline, 0).length === 0) + //如果加工洞外圈和最外轮廓相交,则去掉 + if (h.Curve.IntersectWith(outline, 0).length > 0) + continue; + + let isVail = true; + //若最外轮廓内偏移一个刀半径的曲线 和最内轮廓相交或者被包含,则去掉.且不与洞曲线相等 + if (isOut) + { + let tmpCus = outline.GetOffsetCurves(dir * offsetDist); + for (let c of tmpCus) + { + if (h.Curve.IntersectWith(c, 0).length > 0) + { + if (!(offsetDist === knifRadius && equalCurve(h.Curve, c))) + { + isVail = false; + break; + } + } + else if (h.Area > c.Area) + { + isVail = false; + break; + } + } + + } + if (isVail) offsetCus.push(h.Curve); } @@ -95,7 +122,6 @@ export class FeedingToolPath extends Singleton } /** * 获得曲线内偏移方向 - * @param cu */ private GetCurveToInDir(cu: Curve): number { @@ -104,11 +130,10 @@ export class FeedingToolPath extends Singleton dir = -1; return dir; } + /** * 开始计算走刀路径 * TODO:圆孔半径===刀半径时推送ys 显示点 - * @param br - * @returns Curve[] */ CalcPath(br: Board): Curve[] { @@ -135,9 +160,7 @@ export class FeedingToolPath extends Singleton { let offsetCus = this.HandleShape(shape, knifeRadius); if (offsetCus.length > 1) - cus.push( - ...OptimizeToolPath(offsetCus, shape, knifeRadius) - ); + cus.push(...OptimizeToolPath(offsetCus, shape, knifeRadius)); } } return cus;