From faaed22302221ec24f1cf013ba1a6840f69a8fe5 Mon Sep 17 00:00:00 2001 From: ChenX Date: Thu, 29 Oct 2020 21:34:56 +0800 Subject: [PATCH] =?UTF-8?q?!1275=20=E4=BC=98=E5=8C=96:=E9=92=88=E5=AF=B9?= =?UTF-8?q?=E8=BD=B4=E5=AF=B9=E9=BD=90=E7=9A=84=E5=85=B3=E8=81=94=E6=8B=89?= =?UTF-8?q?=E6=A7=BD,=E4=BD=BF=E7=94=A8=E5=BF=AB=E9=80=9F=E7=9B=92?= =?UTF-8?q?=E5=AD=90=E6=B1=82=E4=BA=A4=E7=9A=84=E6=96=B9=E5=BC=8F=E6=9D=A5?= =?UTF-8?q?=E7=A1=AE=E5=AE=9A=E6=A7=BD=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../__snapshots__/bool5.test.ts.snap | 2 + __test__/Booloperate/bool5.test.ts | 13 ++++++ src/Add-on/test/TestUtil.ts | 6 ++- src/DatabaseServices/Contour.ts | 9 ++-- src/DatabaseServices/Entity/Circle.ts | 7 +-- src/DatabaseServices/Entity/Extrude.ts | 44 ++++++++++++++++--- src/DatabaseServices/Shape.ts | 4 +- .../ToolPath/FeedingToolPath.ts | 4 +- src/GraphicsSystem/Viewer.ts | 3 ++ src/Reactor/RelevanceCuttingReactor.ts | 4 +- 10 files changed, 78 insertions(+), 18 deletions(-) diff --git a/__test__/Booloperate/__snapshots__/bool5.test.ts.snap b/__test__/Booloperate/__snapshots__/bool5.test.ts.snap index a474aace4..22fa05927 100644 --- a/__test__/Booloperate/__snapshots__/bool5.test.ts.snap +++ b/__test__/Booloperate/__snapshots__/bool5.test.ts.snap @@ -1,5 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`分裂的点在参数周围 1`] = `5782.013217639177`; + exports[`差集共线(圆) 1`] = `442426.78778792813`; exports[`差集错误 1`] = `1216051.1666666665`; diff --git a/__test__/Booloperate/bool5.test.ts b/__test__/Booloperate/bool5.test.ts index 9788c59e0..943e13830 100644 --- a/__test__/Booloperate/bool5.test.ts +++ b/__test__/Booloperate/bool5.test.ts @@ -57,3 +57,16 @@ test("差集错误", () => expect(s.Area).toMatchSnapshot(); }); + +//由于切割的点在参数周围,导致分裂的时候,点出现了偏差(导致原先的算法 点在曲线内部了) +test("分裂的点在参数周围", () => +{ + let d = { "file": [2, "Region", 8, 2, 124, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2997.919883164752, -777.954629938351, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2997.919883164752, -777.954629938351, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2997.919883164752, -777.954629938351, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2997.919883164752, -777.954629938351, 0, 1], 0, 2, 4, [-965, -11], 0, [2603, -11], 0, [2603, 7], 0, [-965, 7], 0, true, 0, "Region", 8, 2, 125, false, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2994.919883164752, -770.954597934382, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2994.919883164752, -770.954597934382, 0, 1], 0, 1, 1, 1, 1, "Polyline", 8, 2, 0, false, 0, 3, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2994.919883164752, -770.954597934382, 0, 1], 0, 0, true, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 2994.919883164752, -777.954629938351, 0, 1], 0, 2, 8, [829, -7.000032003968954], 0, [829, 2131], 0, [3, 2131], 0, [3, 2124.0000000000005], 0, [3, 2124.0000000000005], 0, [3, 0], 0, [3, 0], 0, [3, -7.000032003968954], 0, true, 0], "basePt": { "x": 2032.9198831647518, "y": -788.954629938351, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] }; + + let regs = LoadRegionsFromFileData(d); + + regs[0].BooleanOper(regs[1], BoolOpeartionType.Intersection); + expect(regs[0].ShapeManager.ShapeList.length).toBe(1); + for (let s of regs[0].ShapeManager.ShapeList) + expect(s.Area).toMatchSnapshot(); +}); diff --git a/src/Add-on/test/TestUtil.ts b/src/Add-on/test/TestUtil.ts index d3e077efd..1bee3e40e 100644 --- a/src/Add-on/test/TestUtil.ts +++ b/src/Add-on/test/TestUtil.ts @@ -1,9 +1,11 @@ import { Object3D } from "three"; -import { app } from "../../ApplicationServices/Application"; import { Entity } from "../../DatabaseServices/Entity/Entity"; -export function TestDraw(en: Entity | Entity[] | Object3D | Object3D[], colorIndex = 0) +export async function TestDraw(en: Entity | Entity[] | Object3D | Object3D[], colorIndex = 0) { + let app = (await import("../../ApplicationServices/Application"))?.app; + if (!app) return; + if (en instanceof Object3D) app.Viewer.Scene.add(en); else if (en instanceof Entity) diff --git a/src/DatabaseServices/Contour.ts b/src/DatabaseServices/Contour.ts index 9fadf76cb..17e1469d4 100644 --- a/src/DatabaseServices/Contour.ts +++ b/src/DatabaseServices/Contour.ts @@ -288,7 +288,7 @@ export class Contour if (hasEqualCus) continue; - if (target.CuInOutline(pl)) + if (fastCurveInCurve(targetOutline, pl)) intersectionList.push(pl); else unionList.push(pl); @@ -296,7 +296,7 @@ export class Contour for (let pl of targetCus) { - if (this.CuInOutline(pl)) + if (fastCurveInCurve(sourceOutline, pl)) intersectionList.push(pl); else unionList.push(pl); @@ -590,12 +590,13 @@ function fastEqualCurve(c1: Curve, c2: Curve, tolerance = 1e-3) //对于双多段线互相切割后的结果,快速判断曲线是否在另一条曲线内部 -function fastCurveInCurve(sourceCu: Polyline, targetCu: Polyline) +//也许有一天这个中点算法需要改一下, 使用 src\Geometry\ExtrudeEdgeGeometry2.ts->CenterPoint 会比较稳妥 +function fastCurveInCurve(sourceCu: Polyline | Circle, targetCu: Curve) { return sourceCu.PtInCurve(targetCu.GetPointAtParam(targetCu.EndParam * 0.5)); } -function fastCurveInCurve2(sourceCu: Polyline, targetCu: Polyline) +function fastCurveInCurve2(sourceCu: Polyline | Circle, targetCu: Curve) { return sourceCu.PtInCurve(targetCu.StartPoint) && sourceCu.PtInCurve(targetCu.GetPointAtParam(targetCu.EndParam * 0.5)); diff --git a/src/DatabaseServices/Entity/Circle.ts b/src/DatabaseServices/Entity/Circle.ts index c292c593f..b4014ee02 100644 --- a/src/DatabaseServices/Entity/Circle.ts +++ b/src/DatabaseServices/Entity/Circle.ts @@ -1,4 +1,4 @@ -import { Box3, BufferGeometry, EllipseCurve, Line as TLine, Material, Matrix3, Matrix4, Object3D, Vector3 } from 'three'; +import { BufferGeometry, EllipseCurve, Line as TLine, Material, Matrix3, Matrix4, Object3D, Vector3 } from 'three'; import { Line2 } from 'three/examples/jsm/lines/Line2'; import { LineGeometry } from 'three/examples/jsm/lines/LineGeometry'; import { arrayLast, arrayRemoveDuplicateBySort } from '../../Common/ArrayExt'; @@ -7,6 +7,7 @@ import { getArcOrCirNearPts, GetTanPtsOnArcOrCircle } from '../../Common/CurveUt import { reviseMirrorMatrix } from '../../Common/Matrix4Utils'; import { clamp } from '../../Common/Utils'; import { ObjectSnapMode } from '../../Editor/ObjectSnapMode'; +import { Box3Ext } from '../../Geometry/Box'; import { BufferGeometryUtils } from '../../Geometry/BufferGeometryUtils'; import { angle, AsVector3, equaln, MoveMatrix, polar } from '../../Geometry/GeUtils'; import { IntersectCircleAndArc, IntersectCircleAndCircle, IntersectEllipseAndCircleOrArc, IntersectLineAndCircle, IntersectOption, IntersectPolylineAndCurve, reverseIntersectOption } from '../../GraphicsSystem/IntersectWith'; @@ -236,9 +237,9 @@ export class Circle extends Curve } //******************** Curve function end*****************// - get BoundingBox(): Box3 + get BoundingBox(): Box3Ext { - return new Box3().setFromPoints(this.GetGripPoints()); + return new Box3Ext().setFromPoints(this.GetGripPoints()); } InitDrawObject(renderType: RenderType = RenderType.Wireframe) diff --git a/src/DatabaseServices/Entity/Extrude.ts b/src/DatabaseServices/Entity/Extrude.ts index af54bb227..fa49324be 100644 --- a/src/DatabaseServices/Entity/Extrude.ts +++ b/src/DatabaseServices/Entity/Extrude.ts @@ -143,6 +143,9 @@ export class ExtrudeSolid extends Entity { this.WriteAllObjectRecord(); this.groovesAddLength = v; + + //更改它的时候,关联切割被更新,拆单的时候才会正确,否则使用缓存将不正确 + this.__UpdateVersion__++; } } get GroovesAddWidth() @@ -156,6 +159,9 @@ export class ExtrudeSolid extends Entity { this.WriteAllObjectRecord(); this.groovesAddWidth = v; + + //更改它的时候,关联切割被更新,拆单的时候才会正确,否则使用缓存将不正确 + this.__UpdateVersion__++; } } get GroovesAddDepth() @@ -169,6 +175,9 @@ export class ExtrudeSolid extends Entity { this.WriteAllObjectRecord(); this.groovesAddDepth = v; + + //更改它的时候,关联切割被更新,拆单的时候才会正确,否则使用缓存将不正确 + this.__UpdateVersion__++; } } @@ -495,7 +504,7 @@ export class ExtrudeSolid extends Entity let thisShape = this.Shape; let targetShape = target.Shape.ApplyMatrix(matrixToLocal); - let unionShapes = thisShape.UnionBoolOperation(targetShape); + let unionShapes = thisShape.UnionBoolOperation(targetShape, true); if (unionShapes.length === 1) { this.WriteAllObjectRecord(); @@ -1006,12 +1015,37 @@ export class ExtrudeSolid extends Entity } else { + //当切割刀是矩形板,并且没有槽的时候,如果轴对齐,我们可以直接用aabb进行求交 + if (target.isRect && target.grooves.length === 0) + { + let diffMtx = target.OCS.premultiply(this.OCSInv); + let box = target.BoundingBoxInOCS.applyMatrix4(diffMtx); + let size = box.getSize(new Vector3); + + //轴对齐 + if (equaln(size.x * size.y * size.z, target.Width * target.Height * target.Thickness, 1)) + { + let ibox = this.BoundingBoxInOCS.intersect(box); + if (!(ibox.getSize(size).toArray().every(x => x > 1))) return []; + + //构造新槽(因为我们当前的槽加长是根据槽的长短边进行加长的,所以我们可以这么构建) + let g2 = new ExtrudeSolid().ConverToRectSolid(size.x, size.y, size.z); + g2.Position = ibox.min; + g2.ApplyMatrix(this._Matrix); + g2.groovesAddDepth = target.groovesAddDepth; + g2.groovesAddLength = target.groovesAddLength; + g2.groovesAddWidth = target.groovesAddWidth; + g2.knifeRadius = target.knifeRadius; + return [g2]; + } + } + let grooves: ExtrudeSolid[] = []; let project = ProjectBoard(target, this); if (!project) { - let yv = target.Normal; - let zv = this.Normal; + let yv = n2; + let zv = n1; let xv = yv.clone().cross(zv); yv.copy(zv).cross(xv); let m = new Matrix4().makeBasis(xv, yv, zv).copyPosition(this.OCS); @@ -1055,8 +1089,8 @@ export class ExtrudeSolid extends Entity else outlines.push(c.Curve); } - let xv = this.Normal; - let zv = target.Normal; + let xv = n1; + let zv = n2; let yv = zv.clone().cross(xv); //把<投影轮廓>对齐到肉的侧面坐标系上 diff --git a/src/DatabaseServices/Shape.ts b/src/DatabaseServices/Shape.ts index 43f786568..0ee46a8cd 100644 --- a/src/DatabaseServices/Shape.ts +++ b/src/DatabaseServices/Shape.ts @@ -233,8 +233,10 @@ export class Shape } //并集,如果成功返回1个形状,不成功返回2个形状 - UnionBoolOperation(targetShape: Shape): Shape[] + UnionBoolOperation(targetShape: Shape, checkIntersect = false): Shape[] { + if (checkIntersect && !this.BoundingBox.intersectsBox(targetShape.BoundingBox, 1e-3)) return [this, targetShape]; + let { contours, holes } = this._Outline.UnionBoolOperation(targetShape._Outline); let shapes: Shape[] = []; diff --git a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts index e3e0f1a0f..67e2ad856 100644 --- a/src/GraphicsSystem/ToolPath/FeedingToolPath.ts +++ b/src/GraphicsSystem/ToolPath/FeedingToolPath.ts @@ -138,10 +138,10 @@ export class FeedingToolPath extends Singleton //若最外轮廓内偏移一个刀半径的曲线 和最内轮廓相交或者被包含,则去掉.且不与洞曲线相等 if (isOut) { - let outlineOffsetCus = outline.GetOffsetCurves(dir * knifRadius).filter(c => c.IsClose); + let outlineOffsetCus = outline.GetOffsetCurves(dir * knifRadius).filter(c => c.IsClose) as Curve[]; let outlineCus = GetOffsetCurves(outline, dir * knifRadius); let ho = holeOffsetCus[i]; - let maxArea = Math.max(...outlineOffsetCus.map(c => c.Area)); + let maxArea = Math.max(...(outlineOffsetCus.map(c => c.Area))); for (let j = 0; j < outlineOffsetCus.length; j++) { let c = outlineOffsetCus[j]; diff --git a/src/GraphicsSystem/Viewer.ts b/src/GraphicsSystem/Viewer.ts index d03181b3f..ee096d8f9 100644 --- a/src/GraphicsSystem/Viewer.ts +++ b/src/GraphicsSystem/Viewer.ts @@ -25,6 +25,7 @@ import { PreViewer } from './PreViewer'; import { RenderType } from './RenderType'; import { UpdateDraw } from '../Common/Status'; import { ColorMaterial } from '../Common/ColorPalette'; +import { IsDev } from '../Common/Deving'; export class Viewer { @@ -510,6 +511,7 @@ export class Viewer { const renderModelEntitys = async () => { + console.time("开图渲染"); Entity.__ReadFileIng__ = true; const down = DownPanelStore.GetInstance() as DownPanelStore; @@ -553,6 +555,7 @@ export class Viewer } down.progressName = ""; + console.timeEnd("开图渲染"); }; const renderLayoutEntitys = async () => diff --git a/src/Reactor/RelevanceCuttingReactor.ts b/src/Reactor/RelevanceCuttingReactor.ts index db50a15d3..917315d0e 100644 --- a/src/Reactor/RelevanceCuttingReactor.ts +++ b/src/Reactor/RelevanceCuttingReactor.ts @@ -19,6 +19,8 @@ async function UpdateRelevanceGroove(ents: CADObject[]) { if (ExtrudeConfig.DisableRefCut) return; + console.time("更新关联拉槽"); + let needUpdateBoardSet = new Set(); for (let i = 0; i < ents.length; i++) @@ -58,7 +60,7 @@ async function UpdateRelevanceGroove(ents: CADObject[]) await Sleep(0); } } - + console.timeEnd("更新关联拉槽"); app.Editor.UpdateScreen(); down.EndProgress(); }