!2710 功能: 针对圆弧板的线性切割

pull/2802/MERGE
张子涵 3 months ago committed by ChenX
parent da073aecb7
commit adc659ff5e

@ -0,0 +1,120 @@
import { LinearCuttingForSweep, ViewManager, ViewType } from "../../src/Add-on/BoardCutting/LinearCuttingForSweep";
import { Polyline } from "../../src/DatabaseServices/Entity/Polyline";
import { LoadBoardsFromFileData, LoadEntityFromFileData } from "../Utils/LoadEntity.util";
import "../Utils/jest.util";
// 测试命令(用于复制)npm run test -- ArcBoardCutting.test.ts
/** 批量测试 */
function TestAll()
{
/** 测试集 */
const testSet = new Set([
{
question: {
brData: { "file": [1, "Board", 10, 2, 101, 0, 1, 2, 71, [-1, 6.123233995736766e-17, 0, 0, -6.123233995736766e-17, -1, 2.4492935982947064e-16, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, [6.123233995736766e-17, 1, -2.4492935982947064e-16, 0, -1, 6.123233995736766e-17, 0, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, 3, 600, 1400, 18, true, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 4, [0, 0], 0, [1400, 0], 0, [1400, 600], 0, [0, 600], 0, true, 0, 3, 0, 0, 0, 0, 0, 19, 0, "层板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, null, 0, 0, "", "", "", "", 0, false, 0, "Polyline", 10, 2, 0, 0, 0, 8, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1829.130340136119, -3186.5844897958577, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [600.0000000000002, 0], -0.9999999999999999, [600.0000000000002, -400], 0, [484.8671984825753, -400], 0, false, 0, 0, true, 2, -1, 0, 6, 6, 2, 0, 0, 0, 3, 0, 1, 628.31853, 6, 6, 2, 0, 0, 0, 3, 0], "basePt": { "x": 2313.3906173705936, "y": 938.6530296283928, "z": -1418 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
plData: { "file": [1, "Polyline", 10, 2, 273, 0, 1, 1, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 2, [2008.0513946721885, 1238.653029628393], 0, [3469.88022397831, 1238.653029628393], 0, false], "basePt": { "x": 2008.0513946721885, "y": 1238.653029628393, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
viewStr: ViewType.Down
},
answer: {
count: 2,
areas: [420000, 420000],
lengths: [1343.4513322353837, 1343.4513322353837]
}
},
{
question: {
brData: { "file": [1, "Board", 10, 2, 101, 0, 1, 2, 71, [-1, 6.123233995736766e-17, 0, 0, -6.123233995736766e-17, -1, 2.4492935982947064e-16, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, [6.123233995736766e-17, 1, -2.4492935982947064e-16, 0, -1, 6.123233995736766e-17, 0, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, 3, 600, 1400, 18, true, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 4, [0, 0], 0, [1400, 0], 0, [1400, 600], 0, [0, 600], 0, true, 0, 3, 0, 0, 0, 0, 0, 19, 0, "层板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, null, 0, 0, "", "", "", "", 0, false, 0, "Polyline", 10, 2, 0, 0, 0, 8, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1829.130340136119, -3186.5844897958577, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [600.0000000000002, 0], -0.9999999999999999, [600.0000000000002, -400], 0, [484.8671984825753, -400], 0, false, 0, 0, true, 2, -1, 0, 6, 6, 2, 0, 0, 0, 3, 0, 1, 628.31853, 6, 6, 2, 0, 0, 0, 3, 0], "basePt": { "x": 2313.3906173705936, "y": 938.6530296283928, "z": -1418 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
plData: { "file": [1, "Polyline", 10, 2, 226, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 2, [2980.2949542257415, 1785.8711020734017], 0, [2779.229252050603, 693.9296733376492], 0, false], "basePt": { "x": 2779.229252050603, "y": 693.9296733376492, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
viewStr: ViewType.Down
},
answer: {
count: 2,
areas: [151114.91863862606, 688885.0813613739],
lengths: [307.09899093217655, 1146.8339277054733]
}
},
{
question: {
brData: { "file": [1, "Board", 10, 2, 101, 0, 1, 2, 71, [-1, 6.123233995736766e-17, 0, 0, -6.123233995736766e-17, -1, 2.4492935982947064e-16, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, [6.123233995736766e-17, 1, -2.4492935982947064e-16, 0, -1, 6.123233995736766e-17, 0, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, 3, 600, 1400, 18, true, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 4, [0, 0], 0, [1400, 0], 0, [1400, 600], 0, [0, 600], 0, true, 0, 3, 0, 0, 0, 0, 0, 19, 0, "层板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, null, 0, 0, "", "", "", "", 0, false, 0, "Polyline", 10, 2, 0, 0, 0, 8, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1829.130340136119, -3186.5844897958577, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [600.0000000000002, 0], -0.9999999999999999, [600.0000000000002, -400], 0, [484.8671984825753, -400], 0, false, 0, 0, true, 2, -1, 0, 6, 6, 2, 0, 0, 0, 3, 0, 1, 628.31853, 6, 6, 2, 0, 0, 0, 3, 0], "basePt": { "x": 2313.3906173705936, "y": 938.6530296283928, "z": -1418 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
plData: { "file": [1, "Polyline", 10, 2, 229, 0, 1, 7, 0, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 2, [2423.497625125358, 1699.2581842133418], 0, [2494.643950510407, 734.1428137726766], 0, false], "basePt": { "x": 2423.497625125358, "y": 734.1428137726766, "z": 0 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
viewStr: ViewType.Down
},
answer: {
count: 3,
areas: [405352.90503024973, 320214.5090290456, 114432.58594070456],
lengths: [691.2561564438456, 532.3117909155627, 206.38895796127028]
}
},
{
question: {
brData: { "file": [1, "Board", 10, 2, 101, 0, 1, 2, 71, [-1, 6.123233995736766e-17, 0, 0, -6.123233995736766e-17, -1, 2.4492935982947064e-16, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, [6.123233995736766e-17, 1, -2.4492935982947064e-16, 0, -1, 6.123233995736766e-17, 0, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, 3, 600, 1400, 18, true, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 4, [0, 0], 0, [1400, 0], 0, [1400, 600], 0, [0, 600], 0, true, 0, 3, 0, 0, 0, 0, 0, 19, 0, "层板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, null, 0, 0, "", "", "", "", 0, false, 0, "Polyline", 10, 2, 0, 0, 0, 8, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1829.130340136119, -3186.5844897958577, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [600.0000000000002, 0], -0.9999999999999999, [600.0000000000002, -400], 0, [484.8671984825753, -400], 0, false, 0, 0, true, 2, -1, 0, 6, 6, 2, 0, 0, 0, 3, 0, 1, 628.31853, 6, 6, 2, 0, 0, 0, 3, 0], "basePt": { "x": 2313.3906173705936, "y": 938.6530296283928, "z": -1418 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
plData: { "file": [1, "Polyline", 10, 2, 232, 0, 1, 7, 71, [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 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, 2, [-1287.5623052437588, -738.1797530758489], 0, [-1129.9916386341743, -1642.7520984271673], 0, false], "basePt": { "x": 0, "y": 1129.9916386341743, "z": -1642.7520984271673 }, "ucs": [0, -1, 0, 0, 0, 0, 1, 0, -1, 0, 0, 0, 0, 0, 0, 1] },
viewStr: ViewType.Left
},
answer: {
count: 2,
areas: [445744.72443803976, 394255.27556196053],
lengths: [1343.4513322353837, 1343.4513322353837]
}
},
{
question: {
brData: { "file": [1, "Board", 10, 2, 101, 0, 1, 2, 71, [-1, 6.123233995736766e-17, 0, 0, -6.123233995736766e-17, -1, 2.4492935982947064e-16, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, [6.123233995736766e-17, 1, -2.4492935982947064e-16, 0, -1, 6.123233995736766e-17, 0, 0, 1.4997597826618576e-32, 2.4492935982947064e-16, 1, 0, 3131.3906173705936, 1538.653029628393, -1000, 1], 0, 0, 1, 3, 600, 1400, 18, true, "Polyline", 10, 2, 0, 0, 0, 7, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 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, 4, [0, 0], 0, [1400, 0], 0, [1400, 600], 0, [0, 600], 0, true, 0, 3, 0, 0, 0, 0, 0, 19, 0, "层板", "", "", "", "", "", 0, 0, "三合一", 2, 0, "1", "1", "1", "1", "", "", "", 4, "三合一", "三合一", "三合一", "三合一", true, true, 0, 0, 0, 0, 0, 0, 0, 0, true, 0, 0, null, 0, 0, "", "", "", "", 0, false, 0, "Polyline", 10, 2, 0, 0, 0, 8, 71, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1], 0, 0, 1, [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, -1829.130340136119, -3186.5844897958577, 0, 1], 0, 0, 1, 2, 4, [0, 0], 0, [600.0000000000002, 0], -0.9999999999999999, [600.0000000000002, -400], 0, [484.8671984825753, -400], 0, false, 0, 0, true, 2, -1, 0, 6, 6, 2, 0, 0, 0, 3, 0, 1, 628.31853, 6, 6, 2, 0, 0, 0, 3, 0], "basePt": { "x": 2313.3906173705936, "y": 938.6530296283928, "z": -1418 }, "ucs": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1] },
plData: { "file": [1, "Polyline", 10, 2, 262, 0, 1, 7, 0, [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 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, 2, [2431.3906173705936, -832.5194311579985], 0, [2431.3906173705936, -1547.4552636415062], 0, false], "basePt": { "x": 2431.3906173705936, "y": 0, "z": -1547.4552636415062 }, "ucs": [1, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1] },
viewStr: ViewType.Front
},
answer: {
count: 3,
areas: [422332.63627688476, 286255.04653577565, 131412.31718733965],
lengths: [695.3098414019644, 437.6988479140293, 210.44264291938927]
}
}
]);
// 遍历测试集
testSet.forEach(e =>
{
TestOne(e.question.brData, e.question.plData, e.question.viewStr, e.answer.count, e.answer.areas, e.answer.lengths);
});
}
TestAll();
/**
* @param brData
* @param plData
* @param viewStr
* @param count
* @param areas
* @param lengths
*/
function TestOne(brData: Record<string, any>, plData: Record<string, any>, viewType: ViewType, count: number, areas: number[], lengths: number[])
{
/** 视图 */
const viewMatrix = ViewManager.GetViewMatrix(viewType);
/** 肉 */
const br = LoadBoardsFromFileData(brData)[0];
br.ArcBuild.ParseSweepCurves();
/** 刀 */
const splitPl = LoadEntityFromFileData(plData)[0] as Polyline;
/** 切割器 */
const linearCuttingForSweep = new LinearCuttingForSweep(br, splitPl);
// 单元测试
test(`切割圆弧板-${viewType}`, () =>
{
const [cus, sweepPaths] = linearCuttingForSweep.Split(viewMatrix);
// 板轮廓
expect(cus.length).toBe(count);
for (let i = 0; i < cus.length; i++)
{
const cu = cus[i];
expect(cu.Area).toBeCloseTo(areas[i], 0.1);
}
// 放样路径
expect(sweepPaths.length).toBe(count);
for (let i = 0; i < sweepPaths.length; i++)
{
const sweepPath = sweepPaths[i];
expect(sweepPath.Length).toBeCloseTo(lengths[i], 0.1);
}
});
}

@ -1,12 +1,12 @@
import { Intent } from "@blueprintjs/core";
import { Line3, Matrix4, Vector3 } from "three";
import { Line3, Matrix4, Quaternion, Vector3 } from "three";
import { app } from "../../ApplicationServices/Application";
import { arrayLast, arrayRemoveIf } from "../../Common/ArrayExt";
import { AlignLineGroupRecord } from "../../DatabaseServices/AlignLine/AlignLineGroupRecord";
import { Contour } from "../../DatabaseServices/Contour";
import { Board, I2DModeling } from "../../DatabaseServices/Entity/Board";
import { ExtrudeContourCurve } from "../../DatabaseServices/Entity/Extrude";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { BUL_IS_LINE_FUZZ, Polyline } from "../../DatabaseServices/Entity/Polyline";
import { HardwareCompositeEntity } from "../../DatabaseServices/Hardware/HardwareCompositeEntity";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
@ -15,6 +15,7 @@ import { AsVector2, equaln, isParallelTo } from "../../Geometry/GeUtils";
import { PlaneExt } from "../../Geometry/Plane";
import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
import { AppToaster } from "../../UI/Components/Toaster";
import { LinearCuttingForSweep } from "./LinearCuttingForSweep";
import { SplitPolyline } from "./SplitPolyline";
export class LinearCutting implements Command
@ -56,12 +57,22 @@ export class LinearCutting implements Command
let ucsInv = app.Editor.UCSMatrixInv;
let ucs = app.Editor.UCSMatrix;
/** 刀(多段线) */
const splitPl = LinearCuttingForSweep.CreateSplitPl(pts);
let ptsWcs = pts;//缓存世界坐标系,支持UCS不同时使用捕捉.
pts = pts.map(p => p.clone().applyMatrix4(ucsInv).setZ(0).applyMatrix4(ucs));
for (let br of brs)
{
/** 切割后的板轮廓 */
let cus: Polyline[] = [];
/** 切割后的放样路径 */
let sweepPaths: Polyline[] = [];
/** 用于修正轮廓位置的偏移值 */
let contourBiases: { x: number; y: number; }[] = [];
const sweepPath = br.GetSweepPath();
// 原本的处理方式(针对普通板)
let brNormal = br.Normal;
let isVertical = equaln(brNormal.dot(ucsDir), 0);
let brOcs = br.OCS;
@ -97,7 +108,8 @@ export class LinearCutting implements Command
}
}
if (!bHasInterset)
continue;
if (!sweepPath)
continue;;
}
}
else
@ -143,21 +155,82 @@ export class LinearCutting implements Command
fix2dPath.SetBoardPath2d(br);
br.HandleSpliteEntitys(splitBoards);
continue;
if (!sweepPath)
continue;
}
let cus = SplitPolyline(brContour, clipPls);
// 针对圆弧板进行特殊处理
if (sweepPath)
{
const linearCuttingForSweep = new LinearCuttingForSweep(br, splitPl);
[cus, sweepPaths, contourBiases] = linearCuttingForSweep.Split(ucs, clipPls);
}
else
cus = SplitPolyline(brContour, clipPls);
if (cus.length === 0)
continue;
this.SplitBoard(br, cus);
this.SplitBoard(br, cus, sweepPaths, contourBiases);
}
app.Editor.UCSMatrix = oldUcs;
}
//根据轮廓曲线分裂板件
protected SplitBoard(br: Board, cus: ExtrudeContourCurve[])
/** 针对圆弧板的分裂处理 */
private ProcessForSweepInSplitBoard(br: Board, SweepPaths: Polyline[], contourBiases: { x: number, y: number; }[], index = 0)
{
// 针对圆弧板-修正板的位置板的Position采用contourBiases中的偏移值
if (contourBiases.length > 0)
{
const bias = contourBiases[index];
const ocs = new Matrix4().extractRotation(br.OCS);
const v = new Vector3(bias.x, bias.y, 0).applyMatrix4(ocs);
br.Move(v);
}
// 针对圆弧板-对放样路径进行切割
if (SweepPaths.length > 0)
{
const sweepPath = SweepPaths[index] || SweepPaths[0];
// 若放样路径是一条直线,那就不再是圆弧板了
if (sweepPath.LineData.length === 2 && equaln(sweepPath.LineData[0].bul, BUL_IS_LINE_FUZZ))
{
const sweepAngle = br.SweepAngle;
const sweepPathInWCS = sweepPath.Clone().ApplyMatrix(br.GetSweepPathInWCS().OCS);
// 变成普通板(之后坐标系会错乱,故需要修正)
br.ClearSweepPath();
// 平移修正
const startPoint = sweepPath.StartPoint;
sweepPath.Move(new Vector3(-startPoint.x, -startPoint.y, 0));
const rotateMatrix = new Matrix4().extractRotation(br.OCS);
const biasV = new Vector3(startPoint.x, 0, startPoint.y).applyMatrix4(rotateMatrix);
const biasMatrix = new Matrix4().makeTranslation(biasV.x, biasV.y, biasV.z);
br.ApplyMatrix(biasMatrix);
// 旋转修正
const brStartPoint = new Vector3(0, 0, 0).applyMatrix4(br.OCS);
let brEndPoint = new Vector3(br.Width, 0, 0).applyMatrix4(br.OCS);
// 针对放样角度的处理
if (equaln(sweepAngle, Math.PI / 2))
brEndPoint = new Vector3(0, br.Height, 0).applyMatrix4(br.OCS);
const v1 = brEndPoint.clone().sub(brStartPoint).normalize();
const v2 = sweepPathInWCS.EndPoint.clone().sub(sweepPathInWCS.StartPoint).normalize();
const angle = v1.angleTo(v2);
const rotationAxis = v1.cross(v2).normalize();
const quaternion = new Quaternion().setFromAxisAngle(rotationAxis, angle);
const angleMatrix = new Matrix4().makeRotationFromQuaternion(quaternion);
const moveMatrix = new Matrix4().makeTranslation(br.Position.x, br.Position.y, br.Position.z);
br.OCS = rotateMatrix.premultiply(angleMatrix).premultiply(moveMatrix);
}
else
br.SetSweepPath(sweepPath, br.SweepAngle);
}
}
/** 线
* @param br
* @param cus 线
* @param SweepPaths ()
* @param contourBiases ()
*/
protected SplitBoard(br: Board, cus: ExtrudeContourCurve[], SweepPaths: Polyline[], contourBiases: { x: number, y: number; }[])
{
let spliteEnts: Board[] = [];
@ -172,6 +245,10 @@ export class LinearCutting implements Command
let br2 = br.Clone();
br2.Template = br.Template; // 切割后 模板跟随
br2.ContourCurve = cus[i];
// 针对圆弧板的特殊处理
this.ProcessForSweepInSplitBoard(br2, SweepPaths, contourBiases, i);
app.Database.ModelSpace.Append(br2);
br2.RepairRelevance();
br2.GrooveCheckAllAutoSplit();
@ -193,6 +270,10 @@ export class LinearCutting implements Command
}
br.ContourCurve = cus[0];
// 针对圆弧板的特殊处理
this.ProcessForSweepInSplitBoard(br, SweepPaths, contourBiases);
br.HandleSpliteEntitys(spliteEnts);
br.GrooveCheckAllAutoSplit();

File diff suppressed because it is too large Load Diff

@ -9,9 +9,10 @@ import { IntersectOption } from "../../GraphicsSystem/IntersectWith";
* 线线
* @param {Polyline} meatPl 线
* @param {Polyline[]} knifePls 线
* @return
* @param {boolean} [isSweep = false] (线)
* @return {Polyline[]} 线
*/
export function SplitPolyline(meatPl: Polyline, knifePls: Polyline[]): Polyline[]
export function SplitPolyline(meatPl: Polyline, knifePls: Polyline[], isSweep = false): Polyline[]
{
let allSplitPls: Polyline[] = [];
let allIntersePts: Vector3[] = [];
@ -65,6 +66,12 @@ export function SplitPolyline(meatPl: Polyline, knifePls: Polyline[]): Polyline[
pl.Join(route.curve);
if (pl.Area2 < 0)
pl.Reverse();
// 针对圆弧板特殊处理(去除多余的控制点)
if (isSweep)
{
pl = pl.GetOffsetCurves(10)[0];
pl = pl.GetOffsetCurves(-10)[0];
}
return pl;
});
return cus;

Loading…
Cancel
Save