开发:余料分析:自动裁剪网洞 TestParseOddments

pull/1466/MERGE
ChenX 4 years ago
parent bef21c2cbf
commit 848dc2fe60

@ -208,6 +208,7 @@ import { RenderType } from "../GraphicsSystem/RenderType";
import { Command_TestDrawYHData } from "../Nest/Test/TestDrawYHData";
import { Command_TestNFP } from "../Nest/Test/TestNFP";
import { Command_TestPlace } from "../Nest/Test/TestPlace";
import { Command_TestParseOddments } from "../Nest/Test/TestPraseOddments";
import { Command_TestSaveYHData } from "../Nest/Test/TestSaveYHData";
import { Command_TestSimply } from "../Nest/Test/TestSimply";
import { Command_TestSimplyOddments } from "../Nest/Test/TestSimplyOddments";
@ -516,6 +517,7 @@ export function registerCommand()
commandMachine.RegisterCommand("testYHSave", new Command_TestSaveYHData());
commandMachine.RegisterCommand("testSum", new Command_TestSum());
commandMachine.RegisterCommand("TestSimplyOddments", new Command_TestSimplyOddments());
commandMachine.RegisterCommand("TestParseOddments", new Command_TestParseOddments());//分析余料
}
commandMachine.RegisterCommand("editorlattice", new EditorLattice());

@ -22,12 +22,12 @@ export class Box2
this.max.copy(max);
return this;
}
setFromPoints(points: Vector2[]): Box2
setFromPoints(points: Iterable<Point>): Box2
{
this.makeEmpty();
for (let i = 0, il = points.length; i < il; i++)
for (let p of points)
{
this.expandByPoint(points[i]);
this.expandByPoint(p);
}
return this;
}
@ -69,7 +69,7 @@ export class Box2
{
return this.isEmpty() ? result.set(0, 0) : result.subVectors(this.max, this.min);
}
expandByPoint(point: Vector2): Box2
expandByPoint(point: Point): Box2
{
this.min.min(point);
this.max.max(point);

@ -136,13 +136,13 @@ export class Vector2
{
return this.multiplyScalar(1 / scalar);
}
min(v: Vector2): Vector2
min(v: Point): Vector2
{
this.x = Math.min(this.x, v.x);
this.y = Math.min(this.y, v.y);
return this;
}
max(v: Vector2): Vector2
max(v: Point): Vector2
{
this.x = Math.max(this.x, v.x);
this.y = Math.max(this.y, v.y);

@ -1,4 +1,5 @@
import { ClipInput, ClipType, EndType, JoinType, PolyFillType } from "js-angusj-clipper/web";
import { Box2 } from "../Common/Box2";
import { clipperCpp } from "../Common/ClipperCpp";
import { Container } from "./Container";
import { NestCache } from "./NestCache";
@ -36,20 +37,90 @@ export function ParseOddments(container: Container, binPath: Path, knifeRadius:
});
//所有的余料(使用布尔差集)
let oddmentsPolygon = clipperCpp.lib.clipToPaths({
let oddmentsPolygon = clipperCpp.lib.clipToPolyTree({
subjectInputs: [{ data: binPath.BigIntPoints, closed: true }],
clipInputs: partPaths,
clipType: ClipType.Difference,
subjectFillType: PolyFillType.NonZero
});
//现在我们用树状结构,应该不会自交了?(文档写了,返回的结果不可能重叠或者自交)
//简化结果,避免自交
oddmentsPolygon = clipperCpp.lib.simplifyPolygons(oddmentsPolygon);
// oddmentsPolygon = clipperCpp.lib.simplifyPolygons(oddmentsPolygon);
function CreatePolygon(minx: number, miny: number, maxx: number, maxy: number)
{
return [
{ x: minx, y: miny },
{ x: maxx, y: miny },
{ x: maxx, y: maxy },
{ x: minx, y: maxy },
];
}
let splitPolygons: Path[] = [];
//由于手动排版可能造成余料网洞,我们将网洞的盒子投影,然后裁剪余料,避免余料有网洞
for (let node of oddmentsPolygon.childs)
{
let nodePolygon = node.contour;
//减去网洞
if (node.childs.length)
{
let box = new Box2().setFromPoints(nodePolygon);
let childBoxPolygon = node.childs.map(cnode =>
{
let cbox = new Box2().setFromPoints(cnode.contour);
let type = 0;//0左1右2上3下
let minDist = Infinity;
let letftDist = cbox.min.x - box.min.x;
let rightDist = box.max.x - cbox.max.x;
let topDist = box.max.y - cbox.max.y;
let downDist = cbox.min.y - box.min.y;
if (rightDist < letftDist)
{
type = 1;
minDist = rightDist;
}
if (topDist < minDist)
{
type = 2;
minDist = topDist;
}
if (downDist < minDist)
type = 3;
if (type === 0)
return CreatePolygon(box.min.x, cbox.min.y, cbox.max.x, cbox.max.y);
if (type === 1)
return CreatePolygon(cbox.min.x, cbox.min.y, box.max.x, cbox.max.y);
if (type === 2)
return CreatePolygon(cbox.min.x, cbox.min.y, cbox.max.x, box.max.y);
if (type === 3)
return CreatePolygon(cbox.min.x, box.min.y, cbox.max.x, cbox.max.y);
});
let splits = clipperCpp.lib.clipToPaths({
subjectInputs: [{ data: nodePolygon, closed: true }],
clipInputs: childBoxPolygon.map(polygon => { return { data: polygon }; }),
clipType: ClipType.Difference,
subjectFillType: PolyFillType.NonZero
});
for (let p of splits)
splitPolygons.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 }; }),));
}
let OddmentsPaths: Path[] = [];
for (let polygon of oddmentsPolygon)
for (let polygonPath of splitPolygons)
{
let polygonPath = new Path(PathScale(polygon, 1e-4));
//先获取内部的nfp
let insideNFPS = polygonPath.GetInsideNFP(squarePath);

@ -0,0 +1,46 @@
import { TestDraw } from "../../Add-on/test/TestUtil";
import { app } from "../../ApplicationServices/Application";
import { Polyline } from "../../DatabaseServices/Entity/Polyline";
import { Command } from "../../Editor/CommandMachine";
import { PromptStatus } from "../../Editor/PromptResult";
import { AsVector2, AsVector3 } from "../../Geometry/GeUtils";
import { HotCMD } from "../../Hot/HotCommand";
import { InitClipperCpp } from "../Common/ClipperCpp";
import { Path2Polyline } from "../Converter/Path2Polyline";
import { Container } from "../Core/Container";
import { ParseOddments } from "../Core/ParseOddments";
import { Part } from "../Core/Part";
import { Path } from "../Core/Path";
@HotCMD
export class Command_TestParseOddments implements Command
{
async exec()
{
InitClipperCpp();
let ssRes = await app.Editor.GetSelection({ Filter: { filterTypes: [Polyline] } });
if (ssRes.Status !== PromptStatus.OK) return;
let ents = ssRes.SelectSet.SelectEntityList as Polyline[];
let binPath = new Path(ents[0].GetStretchPoints(), 0);
let container = new Container();
for (let i = 1; i < ents.length; i++)
{
let part = new Part();
let path = new Path(ents[i].GetStretchPoints(), 0);
part.Init2(path, binPath, [0]);
part.PlacePosition = AsVector2(path.OrigionMinPoint).multiplyScalar(1e4);
container.PlacedParts.push(part);
}
let binP = AsVector3(binPath.OrigionMinPoint).multiplyScalar(1e4);
let odd = ParseOddments(container, binPath);
for (let p of odd)
{
let pl = Path2Polyline(p.Points);
pl.Position = AsVector3(p.OrigionMinPoint).add(binP);
TestDraw(pl, 2);
}
}
}
Loading…
Cancel
Save