修复:余料分析-重叠余料

pull/1469/head
ChenX 4 years ago
parent d2a455ec93
commit 677e6324e7

@ -3,7 +3,7 @@ import { Box2 } from "../Common/Box2";
import { clipperCpp } from "../Common/ClipperCpp"; import { clipperCpp } from "../Common/ClipperCpp";
import { Container } from "./Container"; import { Container } from "./Container";
import { NestCache } from "./NestCache"; 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 SquarePath = NestCache.CreatePath(60, 60, 0);
const CanPutPaths = [ 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) for (let node of oddmentsPolygon.childs)
{ {
@ -112,38 +113,84 @@ export function ParseOddments(container: Container, binPath: Path, knifeRadius:
}); });
for (let p of splits) for (let p of splits)
splitPolygons.push(new Path(PathScale(p, 1e-4))); clipedPaths.push(new Path(PathScale(p, 1e-4)));
} }
else 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[] = []; let OddmentsPaths: Path[] = [];
for (let polygonPath of splitPolygons) for (let polygonPath of clipedPaths)
{ {
//先获取内部的nfp //先获取内部的nfp
let insideNFPS = polygonPath.GetInsideNFP(squarePath); let insideNFPS = polygonPath.GetInsideNFP(squarePath);
if (!insideNFPS) continue; if (!insideNFPS) continue;
let beferPolygons: ClipInput[] = [];
for (let nfp of insideNFPS) for (let nfp of insideNFPS)
{ {
let nfpPath = new Path(PathScale(nfp, 1e-4)); let nfpPath = new Path(PathScale(nfp, 1e-4));
//通过内部nfp还原实际轮廓 //通过内部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); sumPolygons = clipperCpp.lib.simplifyPolygons(sumPolygons);
for (let poly of sumPolygons) for (let poly of sumPolygons)
{ {
if (clipperCpp.lib.area(poly) < 0) continue;//移除内部的,无意义的 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))//能塞的下指定的轮廓才会被留下 if (canPutPaths.some(p => tempPath.GetInsideNFP(p)?.length))//能塞的下指定的轮廓才会被留下
{
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.x += nfpPath.OrigionMinPoint.x + polygonPath.OrigionMinPoint.x;
tempPath.OrigionMinPoint.y += nfpPath.OrigionMinPoint.y + polygonPath.OrigionMinPoint.y; tempPath.OrigionMinPoint.y += nfpPath.OrigionMinPoint.y + polygonPath.OrigionMinPoint.y;
OddmentsPaths.push(tempPath); 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 });//用于裁剪后续的余料
}
}
} }
} }
} }

@ -348,6 +348,16 @@ export function TranslatePath(pts: Point[], p: Point): Point[]
}); });
} }
export function TranslatePath_Self(pts: Point[], mx: number, my: number): Point[]
{
for (let pt of pts)
{
pt.x += mx;
pt.y += my;
}
return pts;
}
//缩放点表,返回原始点表 //缩放点表,返回原始点表
export function PathScale(pts: Point[], scale: number): Point[] export function PathScale(pts: Point[], scale: number): Point[]
{ {

@ -36,11 +36,13 @@ export class Command_TestParseOddments implements Command
let binP = AsVector3(binPath.OrigionMinPoint).multiplyScalar(1e4); let binP = AsVector3(binPath.OrigionMinPoint).multiplyScalar(1e4);
let odd = ParseOddments(container, binPath); let odd = ParseOddments(container, binPath);
let i = 1;
for (let p of odd) for (let p of odd)
{ {
let pl = Path2Polyline(p.Points); let pl = Path2Polyline(p.Points);
pl.Position = AsVector3(p.OrigionMinPoint).add(binP); pl.Position = AsVector3(p.OrigionMinPoint).add(binP);
TestDraw(pl, 2); TestDraw(pl, i);
i++;
} }
} }
} }

@ -76,6 +76,9 @@ export class EntityModal extends React.Component<{ store?: EntityStore; }, {}> {
<li> <li>
: {ents[0].Area.toFixed(2)} : {ents[0].Area.toFixed(2)}
</li> </li>
<li>
: {ents[0].IsClockWise ? "顺时针" : "逆时针"}
</li>
</> </>
} }

@ -116,6 +116,9 @@ export class PropertiesPanel extends React.Component<PropertiesPanelProps, {}>
<li> <li>
:{(ents[0] as Curve).EndParam} :{(ents[0] as Curve).EndParam}
</li> </li>
<li>
: {ents[0].IsClockWise ? "顺时针" : "逆时针"}
</li>
</> </>
} }
{ {

Loading…
Cancel
Save