|
|
|
@ -3,7 +3,7 @@ import { Box2 } from "../Common/Box2";
|
|
|
|
|
import { clipperCpp } from "../Common/ClipperCpp";
|
|
|
|
|
import { Container } from "./Container";
|
|
|
|
|
import { NestCache } from "./NestCache";
|
|
|
|
|
import { Path, PathScale, TranslatePath } from "./Path";
|
|
|
|
|
import { Path, PathScale, TranslatePath, TranslatePath_Self } from "./Path";
|
|
|
|
|
|
|
|
|
|
const SquarePath = NestCache.CreatePath(60, 60, 0);
|
|
|
|
|
const CanPutPaths = [
|
|
|
|
@ -58,7 +58,8 @@ export function ParseOddments(container: Container, binPath: Path, knifeRadius:
|
|
|
|
|
];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let splitPolygons: Path[] = [];
|
|
|
|
|
let clipedPaths: Path[] = [];//已经减去网洞投影的余料轮廓列表
|
|
|
|
|
|
|
|
|
|
//由于手动排版可能造成余料网洞,我们将网洞的盒子投影,然后裁剪余料,避免余料有网洞
|
|
|
|
|
for (let node of oddmentsPolygon.childs)
|
|
|
|
|
{
|
|
|
|
@ -112,38 +113,84 @@ export function ParseOddments(container: Container, binPath: Path, knifeRadius:
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (let p of splits)
|
|
|
|
|
splitPolygons.push(new Path(PathScale(p, 1e-4)));
|
|
|
|
|
clipedPaths.push(new Path(PathScale(p, 1e-4)));
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
splitPolygons.push(new Path(node.contour.map(p => { return { x: p.x * 1e-4, y: p.y * 1e-4 }; }),));
|
|
|
|
|
clipedPaths.push(new Path(node.contour.map(p => { return { x: p.x * 1e-4, y: p.y * 1e-4 }; }),));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let OddmentsPaths: Path[] = [];
|
|
|
|
|
for (let polygonPath of splitPolygons)
|
|
|
|
|
for (let polygonPath of clipedPaths)
|
|
|
|
|
{
|
|
|
|
|
//先获取内部的nfp
|
|
|
|
|
let insideNFPS = polygonPath.GetInsideNFP(squarePath);
|
|
|
|
|
|
|
|
|
|
if (!insideNFPS) continue;
|
|
|
|
|
|
|
|
|
|
let beferPolygons: ClipInput[] = [];
|
|
|
|
|
|
|
|
|
|
for (let nfp of insideNFPS)
|
|
|
|
|
{
|
|
|
|
|
let nfpPath = new Path(PathScale(nfp, 1e-4));
|
|
|
|
|
//通过内部nfp还原实际轮廓
|
|
|
|
|
let sumPolygons = clipperCpp.lib.minkowskiSumPath(nfpPath.BigIntPoints, SquarePath.BigIntPoints, true);
|
|
|
|
|
let sumPolygons = clipperCpp.lib.minkowskiSumPath(nfpPath.BigIntPoints, squarePath.BigIntPoints, true);
|
|
|
|
|
sumPolygons = clipperCpp.lib.simplifyPolygons(sumPolygons);
|
|
|
|
|
|
|
|
|
|
for (let poly of sumPolygons)
|
|
|
|
|
{
|
|
|
|
|
if (clipperCpp.lib.area(poly) < 0) continue;//移除内部的,无意义的
|
|
|
|
|
|
|
|
|
|
let tempPath = new Path(PathScale(poly, 1e-4));
|
|
|
|
|
let tempPath = new Path(poly.map(p => { return { x: p.x * 1e-4, y: p.y * 1e-4 }; }));//这里new一个新的,下面就复用这个
|
|
|
|
|
if (canPutPaths.some(p => tempPath.GetInsideNFP(p)?.length))//能塞的下指定的轮廓才会被留下
|
|
|
|
|
{
|
|
|
|
|
//设置轮廓的位置
|
|
|
|
|
tempPath.OrigionMinPoint.x += nfpPath.OrigionMinPoint.x + polygonPath.OrigionMinPoint.x;
|
|
|
|
|
tempPath.OrigionMinPoint.y += nfpPath.OrigionMinPoint.y + polygonPath.OrigionMinPoint.y;
|
|
|
|
|
OddmentsPaths.push(tempPath);
|
|
|
|
|
if (beferPolygons.length)
|
|
|
|
|
{
|
|
|
|
|
//移动到实际位置
|
|
|
|
|
TranslatePath_Self(poly, (polygonPath.OrigionMinPoint.x + nfpPath.OrigionMinPoint.x) * 1e4, (polygonPath.OrigionMinPoint.y + nfpPath.OrigionMinPoint.y) * 1e4);
|
|
|
|
|
|
|
|
|
|
//在这里裁剪之前的余料轮廓
|
|
|
|
|
let tree = clipperCpp.lib.clipToPolyTree({
|
|
|
|
|
subjectInputs: [{ data: poly, closed: true }],
|
|
|
|
|
clipInputs: beferPolygons,
|
|
|
|
|
clipType: ClipType.Difference,
|
|
|
|
|
subjectFillType: PolyFillType.NonZero
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
for (let node of tree.childs)
|
|
|
|
|
{
|
|
|
|
|
if (node.childs.length) continue;
|
|
|
|
|
|
|
|
|
|
tempPath = new Path(node.contour.map(p => { return { x: p.x * 1e-4, y: p.y * 1e-4 }; }));
|
|
|
|
|
OddmentsPaths.push(tempPath);
|
|
|
|
|
|
|
|
|
|
//偏移2把刀
|
|
|
|
|
let offsetedPolygon = clipperCpp.lib.offsetToPaths({
|
|
|
|
|
delta: knifeRadius * 2e4,
|
|
|
|
|
offsetInputs: [{ data: node.contour, joinType: JoinType.Miter, endType: EndType.ClosedPolygon }]
|
|
|
|
|
})[0];
|
|
|
|
|
beferPolygons.push({ data: offsetedPolygon });//用于裁剪后续的余料
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
//设置轮廓的位置
|
|
|
|
|
tempPath.OrigionMinPoint.x += nfpPath.OrigionMinPoint.x + polygonPath.OrigionMinPoint.x;
|
|
|
|
|
tempPath.OrigionMinPoint.y += nfpPath.OrigionMinPoint.y + polygonPath.OrigionMinPoint.y;
|
|
|
|
|
OddmentsPaths.push(tempPath);
|
|
|
|
|
|
|
|
|
|
//将余料轮廓加入到裁剪轮廓中,用于裁剪后续的余料
|
|
|
|
|
if (insideNFPS.length)
|
|
|
|
|
{
|
|
|
|
|
//移动到实际位置
|
|
|
|
|
TranslatePath_Self(poly, (polygonPath.OrigionMinPoint.x + nfpPath.OrigionMinPoint.x) * 1e4, (polygonPath.OrigionMinPoint.y + nfpPath.OrigionMinPoint.y) * 1e4);
|
|
|
|
|
//偏移2把刀
|
|
|
|
|
let offsetedPolygon = clipperCpp.lib.offsetToPaths({
|
|
|
|
|
delta: knifeRadius * 2e4,
|
|
|
|
|
offsetInputs: [{ data: poly, joinType: JoinType.Miter, endType: EndType.ClosedPolygon }]
|
|
|
|
|
})[0];
|
|
|
|
|
beferPolygons.push({ data: offsetedPolygon });//用于裁剪后续的余料
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|