using System;
|
using System.Collections.Generic;
|
using System.Linq;
|
using System.Text;
|
using System.Drawing;
|
using netDxf;
|
using System.Windows.Forms;
|
using System.IO;
|
using MyGlassEdit;
|
using netDxf.Entities;
|
using System.Diagnostics;
|
using MyGlassEdit.ng.optima.model;
|
using Newtonsoft.Json;
|
using ng.optima.server;
|
using ng.optima.model;
|
|
namespace directPacking
|
{
|
public class Stock
|
{
|
public int StockID;
|
public int StockCount;
|
public string dxfstr;
|
public string rms;
|
public string pls;
|
public string Heard;
|
public string projectInfostr;
|
public string glasstype = "";
|
public string orderName;
|
public string thick = "";
|
public int Stockcount;
|
public int OriginID;
|
public int PolysID;
|
|
public float X;
|
public float Y;
|
public float Width;//实际使用的大小,不加修边
|
public float Height;
|
public float realwidth;//真正的大小,加上修边
|
public float realheight;
|
public List<Polygon> polys = new List<Polygon>();//output
|
public List<FRectangle> remains = new List<FRectangle>();//output
|
public List<CutLine> cutlines = new List<CutLine>();
|
public List<Polygon> expandedPolys = new List<Polygon>();
|
public List<int> deletedRemainsIndexs = new List<int>();
|
public List<FRectangle> rects = new List<FRectangle>();//矩形成品列表
|
public OnePacking pack;//所属的pack
|
public string singleUsage = "";
|
public double Usage = 0;//用于ERP上传
|
public string wuliaodaima = "";
|
public int stockNumber;
|
public int mergedSumStocks = 0;
|
public int sumOfStocks;
|
public int sameCount = 1;
|
public int lingliaoCount = 0;
|
public int originStocksnumber;//Stock的index
|
public long pack_id = 0;
|
public bool hasbeenXmirrored = false;
|
public bool hasbeenYmirrored = false;
|
public float Thickness = 5;
|
public double L;//磨边距
|
|
public float Up = 0;//修边距离
|
public float Down = 0;
|
public float Left = 0;
|
public float Right = 0;
|
public int count = 1000;
|
public int polycount = 0;
|
public double polyarea = 0;
|
public string customname = "";
|
public float price;
|
public string supplyer = "";//供应商
|
public string glassType = "白玻";//玻璃类型
|
public string position = "";//仓库位置
|
public bool isRemainder = false;
|
public string remainpos = "";
|
public Color lineColor = Color.Black;
|
public List<Polygon> Contains = new List<Polygon>();
|
public bool LowE = false;
|
public float usage;//切裁率
|
public bool canbeshowed = true;
|
public List<List<FRectangle>> ganghuarects = new List<List<FRectangle>>();
|
public bool beenCut = false;//该片是否被切割过
|
public bool isMerged = false;//是否在合并的原片里
|
public int hascut = 0;
|
public List<string> log = new List<string>();//测试用的
|
public bool manual = false;
|
public int cutlineCount = 0;
|
public string layer = "X";//优化过程层深控制
|
public int originSameCount = 1;
|
public string packingname = "";
|
public Rectangle rect;
|
public Stock(float x, float y, float w, float h)
|
{
|
X = x;
|
Y = y;
|
Width = w;
|
Height = h;
|
Thickness = (float)0.02;
|
}
|
public Stock(float x, float y, float w, float h, float t)
|
{
|
X = x;
|
Y = y;
|
Width = w;
|
Height = h;
|
Thickness = t;
|
}
|
public Stock()
|
{ }
|
public string ABS_Serialize()
|
{
|
if (polycount == 0) polycount = polys.Count;
|
if (polyarea == 0) polyarea = getArea();
|
if (Usage == 0) Usage = get_usage();
|
string str = "";
|
for (int i = 0; i < polys.Count; i++)
|
str += polys[i].ABS_Serialize()[0] + "⑦";
|
if (str.Length > 0)
|
str = str.Substring(0, str.Length - 1);//polys打包成str
|
|
string dxfstr = "";
|
for (int i = 0; i < polys.Count; i++)
|
dxfstr += polys[i].ABS_Serialize()[1] + "⑦";
|
if (dxfstr.Length > 0)
|
dxfstr = dxfstr.Substring(0, dxfstr.Length - 1);//dxfpolys打包成dxfstr
|
|
return Width.ToString() + "④" +
|
Height + "④" +
|
polycount + "④" +
|
glassType + "④" +
|
Thickness + "④" +
|
supplyer + "④" +
|
sameCount + "④" +
|
Usage + "④" +
|
polyarea + "④" +
|
wuliaodaima + "④" +
|
price + "④" +
|
hascut + "④" +
|
originSameCount + "④" +
|
finished + "④" +
|
start + "④" +
|
stockNumber + "④" +
|
packingname + "④" +
|
realwidth + "④" +
|
realheight + "④" +
|
str + "④" +
|
dxfstr;
|
}
|
public void ABS_Deserialize(string line)
|
{
|
string[] words = line.Split('④');
|
Width = (float)Convert.ToDouble(words[0]);
|
Height = (float)Convert.ToDouble(words[1]);
|
polycount = Convert.ToInt32(words[2]);
|
glassType = words[3];
|
Thickness = (float)Convert.ToDouble(words[4]);
|
supplyer = words[5];
|
sameCount = Convert.ToInt32(words[6]);
|
Usage = Convert.ToDouble(words[7]);
|
polyarea = Convert.ToDouble(words[8]);
|
wuliaodaima = words[9];
|
price = (float)Convert.ToDouble(words[10]);
|
hascut = Convert.ToInt32(words[11]);
|
//MES新增
|
this.originSameCount = Convert.ToInt32(words[12]);
|
this.finished = Convert.ToBoolean(words[13]);
|
this.start = Convert.ToBoolean(words[14]);
|
this.stockNumber = Convert.ToInt32(words[15]);
|
this.packingname = words[16];
|
this.realwidth = (float)Convert.ToDouble(words[17]);
|
this.realheight = (float)Convert.ToDouble(words[18]);
|
string[] str = words[19].Split('⑦');
|
string[] dxfstr = words[20].Split('⑦');
|
for (int i = 0; i < str.Length; i++)
|
{
|
List<string> s = new List<string>();
|
s.Add(str[i]);
|
s.Add(dxfstr[i]);
|
directPacking.Polygon poly = new directPacking.Polygon();
|
if (s[0] != "") poly.ABS_Deserialize(s[0]);
|
if (s[1].Trim() != "")
|
{
|
s.RemoveAt(0);
|
string d = string.Join("\r\n", s);
|
poly.dxfpoly = new dxfPolygon();
|
poly.dxfpoly.ABS_Deserialize(d);
|
}
|
poly.setWidthHeight(false, true);
|
if (poly != null) polys.Add(poly);
|
}
|
}
|
public string Serialize()
|
{
|
if (polycount == 0) polycount = polys.Count;
|
if (polyarea == 0) polyarea = getArea();
|
if (Usage == 0) Usage = get_usage();
|
return Width.ToString() + "④" +
|
Height + "④" +
|
polycount + "④" +
|
glassType + "④" +
|
Thickness + "④" +
|
supplyer + "④" +
|
sameCount + "④" +
|
Usage + "④" +
|
polyarea + "④" +
|
wuliaodaima + "④" +
|
price + "④" +
|
hascut + "④" +
|
originSameCount + "④" +
|
finished + "④" +
|
start + "④" +
|
stockNumber + "④" +
|
packingname + "④" +
|
realwidth + "④" +
|
realheight;
|
}
|
public void Deserialize(string line)
|
{
|
string[] words = line.Split('④');
|
Width = (float)Convert.ToDouble(words[0]);
|
Height = (float)Convert.ToDouble(words[1]);
|
polycount = Convert.ToInt32(words[2]);
|
glassType = words[3];
|
Thickness = (float)Convert.ToDouble(words[4]);
|
supplyer = words[5];
|
sameCount = Convert.ToInt32(words[6]);
|
Usage = Convert.ToDouble(words[7]);
|
polyarea = Convert.ToDouble(words[8]);
|
wuliaodaima = words[9];
|
price = (float)Convert.ToDouble(words[10]);
|
hascut = Convert.ToInt32(words[11]);
|
//MES新增
|
this.originSameCount = Convert.ToInt32(words[12]);
|
this.finished = Convert.ToBoolean(words[13]);
|
this.start = Convert.ToBoolean(words[14]);
|
this.stockNumber = Convert.ToInt32(words[15]);
|
this.packingname = words[16];
|
this.realwidth = (float)Convert.ToDouble(words[17]);
|
this.realheight = (float)Convert.ToDouble(words[18]);
|
}
|
public List<Polygon> expandPolys()
|
{
|
List<Polygon> result = new List<Polygon>();
|
foreach (Polygon poly in polys)
|
{
|
if (poly.Contains.Count > 1)
|
{
|
for (int i = 0; i <= poly.Contains.Count - 1; i++)
|
|
{
|
poly.Contains[i].parent = poly;
|
result.Add(poly.Contains[i]);
|
}
|
}
|
else
|
result.Add(poly);
|
}
|
for (int i = result.Count - 1; i > 0; i--)
|
{
|
for (int j = 0; j < i; j++)
|
{
|
if ((result[j].min_x - result[j].left) * 10000 + result[j].min_y > (result[j + 1].min_x - result[j + 1].left) * 10000 + result[j + 1].min_y)
|
{
|
Polygon temp = result[j];
|
result[j] = result[j + 1];
|
result[j + 1] = temp;
|
}
|
}
|
}
|
this.expandedPolys = result;
|
return result;
|
}
|
public void mergePerfectRemain()
|
{
|
foreach (FRectangle r in remains)
|
if (mergeRemains(r, ref remains, 1))
|
{
|
mergePerfectRemain();
|
return;
|
}
|
foreach (FRectangle r in remains)
|
if (mergeRemains(r, ref remains, 2))
|
{
|
mergePerfectRemain();
|
return;
|
}
|
}
|
public string toTaskString()
|
{
|
if (glassType == null) glassType = "未知类型";
|
return (Width).ToString() + "×" + (Height).ToString() + "×" + sameCount.ToString() + "/" + originSameCount + "[" + Thickness + "mm " + glassType.Trim() + "]";
|
}
|
private bool mergeRemains(FRectangle remain, ref List<FRectangle> remains, int direction)//1-向右,2-向下 原点左上
|
{
|
bool done = false;
|
bool merge = true;
|
if (direction == 1)
|
{
|
while (merge)
|
{
|
merge = false;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
if (remains[i].Height == remain.Height && remains[i].Y + remains[i].Height == remain.Y + remain.Height && remains[i].X == remain.X + remain.Width)
|
{
|
remains.Add(new FRectangle(remain.X, remain.Y, remain.Width + remains[i].Width, remain.Height));
|
remains.Remove(remains[i]);
|
remains.Remove(remain);
|
merge = true;
|
done = true;
|
remain = remains[remains.Count - 1];
|
break;
|
}
|
}
|
}
|
}
|
else
|
{
|
while (merge)
|
{
|
merge = false;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
if (remains[i].Width == remain.Width && remains[i].X + remains[i].Width == remain.X + remain.Width && remains[i].Y == remain.Y + remain.Height)
|
{
|
remains.Add(new FRectangle(remain.X, remain.Y, remain.Width, remain.Height + remains[i].Height));
|
remains.Remove(remains[i]);
|
remains.Remove(remain);
|
merge = true;
|
done = true;
|
remain = remains[remains.Count - 1];
|
break;
|
}
|
}
|
}
|
}
|
return done;
|
}
|
public string getPackingInfo(string str)
|
{
|
return "页码:" + stockNumber.ToString() + "/" + sumOfStocks.ToString() + " 尺寸:" + Width.ToString() + "X" + Height + " 面积:" + (getPolysArea("dd") / 1000000).ToString() + singleUsage;
|
}
|
public float getArea()
|
{
|
return Width * Height;
|
}
|
public Bitmap getbitmap(float width, float height, Color stockColor, List<dxfPolygon> originPolys = null)
|
{
|
float ratio = Math.Min(width / Width, height / Height);
|
Bitmap paper = new Bitmap((int)(Width * ratio) + 2, (int)(Height * ratio) + 2);
|
Graphics g = Graphics.FromImage(paper);
|
drawPolys(g, ratio, stockColor, false);
|
return paper;
|
}
|
public Bitmap getbitmap(float width, float height, Color stockColor, Color polyColor, List<dxfPolygon> originPolys = null)
|
{
|
float ratio = Math.Min(width / Width, height / Height);
|
Bitmap paper = new Bitmap((int)(Width * ratio) + 2, (int)(Height * ratio) + 2);
|
Graphics g = Graphics.FromImage(paper);
|
|
foreach (Polygon poly in polys)
|
if (poly.used)
|
{
|
poly.color = Color.LightSteelBlue;
|
|
}
|
else
|
{
|
poly.color = polyColor;
|
}
|
|
drawPolys(g, ratio, stockColor, false);
|
|
return paper;
|
}
|
public int polysCount()
|
{
|
int sum = 0;
|
foreach (Polygon poly in expandPolys())
|
sum += 1;
|
return sum;
|
}
|
private void drawPolys(Graphics g, float ratio, Color stockColor, bool withInfo = true, string[] polystring = null)
|
{
|
//System.Drawing.Drawing2D.HatchBrush brush;
|
//// 按比例绘制
|
//brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.DottedDiamond, Color.DimGray, Color.White);
|
g.FillRectangle(new SolidBrush(Color.FromArgb(140, stockColor)), 0, 0, (int)(ratio * Width), (int)(ratio * Height));
|
g.DrawRectangle(Pens.DimGray, 0, 0, (int)(ratio * Width - 2), (int)(ratio * Height - 2));
|
foreach (Polygon poly in polys)
|
{
|
#region 选中的改变颜色(不能改变孩子)
|
if (polystring != null)
|
{
|
string ps = poly.getpolystring();
|
if (issame(ps, polystring))
|
poly.color = Colors.selectedColor;
|
}
|
#endregion
|
if (poly.points.Count > 0) poly.draw(g, ratio, withInfo, true, polystring, LowE);
|
}
|
}
|
private bool issame(string s, string[] polystring)
|
{
|
foreach (string ss in polystring)
|
if (s.Trim() == ss.Trim())
|
return true;
|
return false;
|
}
|
public void searchPolygon(ref Polygon selected, int x, int y)
|
{
|
Polygon result = null;
|
foreach (Polygon poly in polys)
|
{
|
if (poly.Contains.Count >= 2)
|
{
|
foreach (Polygon pp in poly.Contains)
|
{
|
pp.parent = poly;
|
if (pp.inPolygon(x, y)) result = pp;
|
}
|
}
|
else
|
if (poly.inPolyRect(x, y)) result = poly;
|
}
|
if (result != null)
|
{
|
selected = result;
|
return;
|
}
|
foreach (Polygon poly in polys)
|
{
|
if (poly.Contains.Count >= 2)
|
{
|
if (poly.inPolyRect(x, y)) result = poly;
|
}
|
}
|
selected = result;
|
}
|
|
/// <summary>
|
/// 自动计算G代码的文件名
|
/// </summary>
|
/// <param name="filename"></param>
|
/// <returns></returns>
|
public string getGfileName(string filename)
|
{
|
string stocknum = (stockNumber + 1).ToString();
|
if (stocknum.Length < 2) stocknum = "0" + stocknum;
|
if (stocknum.Length < 3) stocknum = "0" + stocknum;
|
if (Setting.Weihong)
|
return filename + "_" + stocknum + "_" + ((int)realwidth).ToString() + "×" + ((int)realheight).ToString() + "_" + sameCount.ToString() + ".g";
|
return filename + "_" + stocknum + "_" + sameCount.ToString() + "_" + ((int)realwidth).ToString() + "_" + ((int)realheight).ToString() + ".g";
|
}
|
|
/// <summary>
|
/// 返回DXF文件名
|
/// </summary>
|
/// <param name="filename"></param>
|
/// <param name="directory"></param>
|
/// <param name="projectname"></param>
|
/// <returns></returns>
|
public string getDXFfileName(string filename, string directory, string projectname)
|
{
|
DirectoryInfo dir = new DirectoryInfo(directory + "\\" + projectname);
|
int max = 0;
|
try
|
{
|
foreach (FileInfo file in dir.GetFiles())
|
{
|
if (file.Extension == ".dxf")
|
{
|
string[] words = file.Name.Split('(');
|
string[] str = words[1].Split(')');
|
int index;
|
Int32.TryParse(str[0], out index);
|
if (index > max) max = index;
|
}
|
}
|
}
|
catch (Exception ex) { }
|
return filename + "_" + (stockNumber + 1).ToString() + "_" + sameCount.ToString() + "_" + ((int)Width).ToString() + "_" + ((int)Height).ToString() + ".dxf";
|
}
|
public float polyArea()
|
{
|
float area = 0;
|
|
foreach (Polygon p in expandPolys())
|
{
|
area += p.width * p.height;
|
}
|
return area;
|
}
|
public float polyNetArea()
|
{
|
float area = 0;
|
|
foreach (Polygon p in expandPolys())
|
{
|
p.setArea();
|
area += p.area;
|
}
|
return area;
|
|
}
|
private void addPolys2List(bool hengqie, ref List<Polygon> results, FRectangle box, List<CutLine> lines)
|
{
|
double error = 0.8;
|
List<CutLine> linescopy = new List<CutLine>();
|
foreach (CutLine l in lines)
|
linescopy.Add(l.getCopy());
|
if (hengqie)
|
{
|
for (int i = 0; i < linescopy.Count; i++)
|
{
|
if (((linescopy[i].start.X <= box.X || Math.Abs(linescopy[i].start.X - box.X) < error) &&
|
(linescopy[i].end.X >= box.X + box.Width || Math.Abs(linescopy[i].end.X - box.X - box.Width) < error) &&
|
(linescopy[i].end.Y <= box.Y + box.Height || Math.Abs(linescopy[i].end.Y - box.Y - box.Height) < error) &&
|
linescopy[i].start.Y - box.Y >= error))
|
{ }
|
else
|
{
|
linescopy.RemoveAt(i);
|
i--;
|
}
|
}
|
}
|
else
|
{
|
for (int i = 0; i < linescopy.Count; i++)
|
{
|
if (((linescopy[i].start.Y <= box.Y || Math.Abs(linescopy[i].start.Y - box.Y) < error) &&
|
(linescopy[i].end.Y >= box.Y + box.Height || Math.Abs(linescopy[i].end.Y - box.Y - box.Height) < error) &&
|
(linescopy[i].end.X <= box.X + box.Width || Math.Abs(linescopy[i].end.X - box.X - box.Width) < error) &&
|
linescopy[i].start.X - box.X >= error))
|
{ }
|
else
|
{
|
linescopy.RemoveAt(i);
|
i--;
|
}
|
}
|
linescopy.Reverse();//纵线默认是从左到右,这里需要从右到左
|
}
|
if (linescopy.Count <= 1)
|
{
|
if (hengqie)
|
{
|
foreach (Polygon p in polys)
|
{
|
p.setMaxMin(true);
|
FRectangle r = new FRectangle(p.min_x, p.min_y, p.max_x - p.min_x, p.max_y - p.min_y);
|
if (smallrectinbigrect(r, box))
|
{
|
if (p.Contains.Count >= 2)
|
results.AddRange(p.Contains);
|
else
|
results.Add(p);
|
}
|
}
|
return;
|
}
|
else
|
{
|
addPolys2List(true, ref results, box, lines);
|
return;
|
}
|
}
|
|
if (hengqie)
|
{
|
for (int i = 0; i < linescopy.Count; i++)
|
{
|
FRectangle newbox = new FRectangle(box.X, 0, box.Width, 0);
|
if (i < linescopy.Count - 1)
|
{
|
newbox.Y = linescopy[i + 1].start.Y;
|
newbox.Height = linescopy[i].start.Y - linescopy[i + 1].start.Y;
|
}
|
else
|
{
|
newbox.Y = box.Y;
|
newbox.Height = linescopy[i].start.Y - box.Y;
|
}
|
List<Polygon> innerrects = new List<Polygon>();
|
foreach (Polygon p in polys)
|
{
|
p.setMaxMin(true);
|
FRectangle r = new FRectangle(p.min_x, p.min_y, p.max_x - p.min_x, p.max_y - p.min_y);
|
if (smallrectinbigrect(r, newbox))
|
{
|
innerrects.Add(p);
|
if (innerrects.Count >= 2)
|
break;
|
}
|
}
|
if (innerrects.Count >= 2)
|
addPolys2List(false, ref results, newbox, lines);
|
else if (innerrects.Count == 1)
|
{
|
if (innerrects[0].Contains.Count >= 2)
|
results.AddRange(innerrects[0].Contains);
|
else
|
results.Add(innerrects[0]);
|
}
|
}
|
}
|
else
|
{
|
for (int i = 0; i < linescopy.Count; i++)
|
{
|
FRectangle newbox = new FRectangle(0, box.Y, 0, box.Height);
|
if (i < linescopy.Count - 1)
|
{
|
newbox.X = linescopy[i + 1].start.X;
|
newbox.Width = linescopy[i].start.X - linescopy[i + 1].start.X;
|
}
|
else
|
{
|
newbox.X = box.X;
|
newbox.Width = linescopy[i].start.X - box.X;
|
}
|
List<Polygon> innerrects = new List<Polygon>();
|
foreach (Polygon p in polys)
|
{
|
p.setMaxMin(true);
|
FRectangle r = new FRectangle(p.min_x, p.min_y, p.max_x - p.min_x, p.max_y - p.min_y);
|
if (smallrectinbigrect(r, newbox))
|
{
|
innerrects.Add(p);
|
if (innerrects.Count >= 2)
|
break;
|
}
|
}
|
if (innerrects.Count >= 2)
|
{
|
addPolys2List(true, ref results, newbox, lines);
|
}
|
else if (innerrects.Count == 1)
|
{
|
if (innerrects[0].Contains.Count >= 2)
|
results.AddRange(innerrects[0].Contains);
|
else
|
results.Add(innerrects[0]);
|
}
|
}
|
}
|
}
|
public float get_usage()
|
{
|
float usage;
|
float area = 0;
|
if (globel.IsContainCutEdge)
|
{
|
foreach (FRectangle rect in rects)
|
{
|
area += rect.realwidth * rect.realheight;
|
}
|
usage = area / (realwidth * realheight);
|
}
|
else
|
{
|
foreach (FRectangle rect in rects)
|
{
|
area += rect.Width * rect.Height;
|
}
|
usage = area / (Width * Height);
|
}
|
|
if (usage != 0)
|
{
|
this.usage = usage;
|
return usage;
|
}
|
else
|
{
|
foreach (Polygon p in polys)
|
{
|
p.setWidthHeight(true, true);
|
area += p.width * p.height;
|
}
|
|
}
|
|
this.usage = globel.IsContainCutEdge ? area / (realwidth * realheight) : area / (Width * Height);
|
return globel.IsContainCutEdge ? area / (realwidth * realheight) : area / (Width * Height);
|
}
|
public float getremaindArea()
|
{
|
double sumarea = 0;
|
int index = -1;
|
foreach (FRectangle rect in remains)
|
{
|
index++;
|
if (!deletedRemainsIndexs.Contains(index))
|
sumarea += rect.Width * rect.Height;
|
}
|
return (float)sumarea;
|
}
|
public float getNetusage()
|
{
|
float usage;
|
float area = 0;
|
foreach (FRectangle rect in rects)
|
{
|
area += rect.Width * rect.Height;
|
}
|
usage = area / (Width * Height - getremaindArea());
|
if (usage != 0)
|
{
|
this.usage = usage;
|
return usage;
|
}
|
else
|
{
|
foreach (Polygon p in polys)
|
{
|
area += p.width * p.height;
|
}
|
|
return area / (Width * Height - getremaindArea());
|
}
|
}
|
|
public float getPolysArea(String str)
|
{
|
float area = 0;
|
|
foreach (Polygon p in polys)
|
{
|
|
p.setArea();
|
area += p.area;
|
|
}
|
return area;
|
}
|
public Stock getCopy()
|
{
|
Stock box = new Stock(X, Y, Width, Height);
|
foreach (Polygon p in this.polys)
|
{
|
box.polys.Add(p.getCopy(1));
|
box.polys[box.polys.Count - 1].stock = box;
|
}
|
foreach (FRectangle f in this.rects)
|
{
|
box.rects.Add(f.getcopy());
|
}
|
foreach (List<FRectangle> l in ganghuarects)
|
{
|
List<FRectangle> clone = new List<FRectangle>();
|
foreach (FRectangle r in l)
|
{
|
clone.Add(r.getcopy());
|
}
|
box.ganghuarects.Add(clone);
|
}
|
foreach (string s in log)
|
box.log.Add(s);
|
box.deletedRemainsIndexs = new List<int>();
|
foreach (int a in deletedRemainsIndexs)
|
box.deletedRemainsIndexs.Add(a);
|
foreach (FRectangle f in this.remains)
|
box.remains.Add(new FRectangle(f.X, f.Y, f.Width, f.Height, f.key));
|
box.remainpos = remainpos;
|
box.cutlineCount = cutlineCount;
|
box.manual = manual;
|
box.pack = pack;
|
box.usage = usage;
|
box.L = L;
|
box.Contains = new List<Polygon>();
|
box.stockNumber = stockNumber;
|
box.wuliaodaima = wuliaodaima;//物料代码
|
box.price = price;
|
box.canbeshowed = canbeshowed;
|
box.Left = Left;
|
box.Right = Right;
|
box.Up = Up;
|
box.Down = Down;
|
box.Thickness = Thickness;
|
box.glassType = this.glassType;
|
box.supplyer = supplyer;
|
box.count = count;
|
box.position = position;
|
box.isRemainder = isRemainder;
|
box.realwidth = realwidth;
|
box.realheight = realheight;
|
box.LowE = LowE;
|
box.hasbeenYmirrored = hasbeenYmirrored;
|
box.hasbeenXmirrored = hasbeenXmirrored;
|
box.sameCount = sameCount;
|
box.stockNumber = stockNumber;
|
box.beenCut = beenCut;
|
box.originStocksnumber = originStocksnumber;
|
box.isMerged = isMerged;
|
box.hascut = hascut;
|
box.maxLay = maxLay;
|
box.layer = layer;
|
box.originSameCount = sameCount;
|
box.packingname = packingname;
|
box.start = start;
|
box.finished = finished;
|
|
//box. polys.Clear();
|
//for (int i = 0; i < polys.Count; i++) box.polys.Add(polys[i].getCopy(1));
|
return box;
|
}
|
public float marryFontSize(int width)
|
{
|
float size = (float)width / 6;
|
if (size / (float)1.52 < 1) return 1;
|
return size / (float)1.52;
|
}
|
|
|
#region------------------------------人工干预--------------------------
|
public void X_Mirror()
|
{
|
foreach (FRectangle r in remains)
|
{
|
r.X = this.Width - r.X - r.Width;
|
}
|
foreach (FRectangle r in rects)
|
{
|
r.X = this.Width - r.X - r.Width;
|
}
|
|
List<float> beforeminx = new List<float>();
|
foreach (Polygon p in this.expandedPolys)
|
{
|
p.setMaxMin();
|
beforeminx.Add(p.min_x);
|
}
|
|
for (int j = 0; j < polys.Count; j++)
|
{
|
//修改polys
|
polys[j].X_mirror();
|
polys[j].move(Width, 0);
|
}
|
List<Polygon> _polys = this.expandPolys();
|
for (int j = 0; j < _polys.Count; j++)
|
{
|
if (_polys[j].temp_number == 0)
|
{
|
_polys[j].setMaxMin();
|
if (beforeminx.Count > 0) _polys[j].dxfpoly.Move(_polys[j].min_x - beforeminx[j], 0);
|
_polys[j].dxfpoly.SetPoly();
|
}
|
}
|
float temp = Left;
|
Left = Right;
|
Right = temp;
|
|
this.hasbeenXmirrored = !hasbeenXmirrored;
|
blocks = null;
|
}
|
//现在的情况是,X镜像使用的原理是所有的POLY自己镜像加移动,dxfpoly只move不镜像
|
//Y镜像是poly移动之后再在原位置镜像,dxfpoly也镜像
|
public void Y_Mirror()
|
{
|
foreach (FRectangle r in remains)
|
{
|
r.Y = this.Height - r.Y - r.Height;
|
}
|
rects.Clear();
|
foreach (Polygon r in polys)
|
{
|
FRectangle rect = new FRectangle(r.X, r.Y, r.width, r.height);
|
rects.Add(rect);
|
}
|
foreach (FRectangle r in rects)
|
{
|
r.Y = this.Height - r.Y - r.Height;
|
}
|
|
List<float> beforeminy = new List<float>();
|
foreach (Polygon p in this.expandPolys())
|
{
|
p.setMaxMin();
|
beforeminy.Add(p.min_y);
|
}
|
|
for (int j = 0; j < polys.Count; j++)
|
{
|
polys[j].Y_mirror();
|
polys[j].move(0, Height);
|
}
|
|
#region 移动dxfpoly
|
List<Polygon> _polys = this.expandPolys();
|
for (int j = 0; j < _polys.Count; j++)
|
{
|
if (_polys[j].temp_number == 0)
|
{
|
_polys[j].setMaxMin();
|
_polys[j].dxfpoly.Y_Mirror(this.Height);
|
_polys[j].dxfpoly.SetPoly();
|
}
|
}
|
#endregion
|
|
float temp = Up;
|
Up = Down;
|
Down = temp;
|
this.hasbeenYmirrored = !hasbeenYmirrored;
|
blocks = null;
|
}
|
public void Move(float x, float y)
|
{
|
for (int j = 0; j < polys.Count; j++)
|
{
|
polys[j].move(x, y);
|
}
|
}
|
|
public bool PolyRotate(Polygon selected)
|
{
|
if (selected == null)
|
return false;
|
selected.setMaxMin(true);
|
float w = selected.max_x - selected.min_x;
|
float h = selected.max_y - selected.min_y;
|
FRectangle afterrect;
|
if (this.hasbeenYmirrored && hasbeenXmirrored)
|
afterrect = new FRectangle(selected.max_x - h, selected.max_y - w, h, w);
|
else if (this.hasbeenYmirrored)
|
afterrect = new FRectangle(selected.min_x, selected.max_y - w, h, w);
|
else if (this.hasbeenXmirrored)
|
afterrect = new FRectangle(selected.max_x - h, selected.min_y, h, w);
|
else
|
afterrect = new FRectangle(selected.min_x, selected.min_y, h, w);
|
|
|
if (afterrect.X < 0 || afterrect.X + afterrect.Width > this.Width || afterrect.Y < 0 || afterrect.Y + afterrect.Height > this.Height)
|
{
|
return false;
|
}
|
bool haspoly = false;
|
float minx, miny, maxx, maxy;
|
foreach (Polygon p in this.polys)
|
{
|
p.setWidthHeight(true, true);
|
if (p.getpolystring() == selected.getpolystring()) continue;
|
minx = Math.Max(afterrect.X, p.min_x);
|
miny = Math.Max(afterrect.Y, p.min_y);
|
maxx = Math.Min(afterrect.X + afterrect.Width, p.max_x);
|
maxy = Math.Min(afterrect.Y + afterrect.Height, p.max_y);
|
if (maxx - minx > 1.5 && maxy - miny > 1.5)
|
{
|
haspoly = true;
|
break;
|
}
|
}
|
if (haspoly)
|
{
|
return false;
|
}
|
else
|
{
|
if (this.hasbeenYmirrored && hasbeenXmirrored)
|
{
|
maxx = selected.max_x;
|
maxy = selected.max_y;
|
selected.rotate(Math.PI / 2);
|
selected.fit();
|
w = selected.max_x - selected.min_x;
|
h = selected.max_y - selected.min_y;
|
selected.move(maxx - w, maxy - h);
|
selected.move(-selected.right, -selected.down);
|
}
|
else if (this.hasbeenYmirrored)
|
{
|
minx = selected.min_x;
|
maxy = selected.max_y;
|
selected.rotate(Math.PI / 2);
|
selected.fit();
|
w = selected.max_x - selected.min_x;
|
h = selected.max_y - selected.min_y;
|
selected.move(minx, maxy - h);
|
selected.move(selected.left, -selected.down);
|
}
|
else if (this.hasbeenXmirrored)
|
{
|
maxx = selected.max_x;
|
miny = selected.min_y;
|
selected.rotate(Math.PI / 2);
|
selected.fit();
|
w = selected.max_x - selected.min_x;
|
h = selected.max_y - selected.min_y;
|
selected.move(maxx - w, miny);
|
selected.move(-selected.right, selected.top);
|
}
|
else
|
{
|
minx = selected.min_x;
|
miny = selected.min_y;
|
selected.rotate(Math.PI / 2);
|
selected.fit();
|
w = selected.max_x - selected.min_x;
|
h = selected.max_y - selected.min_y;
|
selected.move(minx, miny);
|
selected.move(selected.left, selected.top);
|
}
|
foreach (Polygon p in selected.Contains)
|
PolyRotate(p);
|
|
setRemains();
|
return true;
|
}
|
}
|
|
List<Polygon> polysclone = new List<Polygon>();
|
public void PolyLeft(Polygon selected)
|
{
|
if (selected != null)
|
{
|
if (selected.parent != null)
|
selected = selected.parent;
|
selected.setWidthHeight(false, true);
|
List<FRectangle> rects = new List<FRectangle>();
|
foreach (Polygon p in this.polys)
|
{
|
p.setWidthHeight(true, true);
|
if (p.getpolystring() != selected.getpolystring() &&
|
(p.max_x <= selected.min_x || Math.Abs(p.max_x - selected.min_x) < 1.5))
|
rects.Add(new FRectangle(p.min_x, p.min_y, p.width, p.height));
|
}
|
float i = 5;
|
bool collide = false;
|
FRectangle nowrect;
|
while (!collide)
|
{
|
nowrect = new FRectangle(selected.min_x - i, selected.min_y, selected.width, selected.height);
|
foreach (FRectangle r in rects)
|
{
|
if (Functions.hassameArea(r, nowrect))
|
{
|
collide = true;
|
i = selected.min_x - r.X - r.Width;
|
break;
|
}
|
}
|
if (selected.min_x - i <= Setting.LeftWidth)
|
{
|
collide = true;
|
i = selected.min_x - Setting.LeftWidth;
|
}
|
if (!collide)
|
i += 5;
|
}
|
|
if (i != 0)
|
{
|
selected.move(-i, 0);
|
if (selected.Contains.Count > 1)
|
{
|
foreach (Polygon o in selected.Contains)
|
{
|
if (o.temp_number == 0)
|
o.dxfpoly.Move(-i, 0);
|
}
|
}
|
else if (selected.temp_number == 0)
|
selected.dxfpoly.Move(-i, 0);
|
setRemains();
|
SetCutlines();
|
}
|
}
|
}
|
public void PolyRight(Polygon selected)
|
{
|
if (selected != null)
|
{
|
if (selected.parent != null)
|
selected = selected.parent;
|
selected.setWidthHeight(false, true);
|
List<FRectangle> rects = new List<FRectangle>();
|
foreach (Polygon p in this.polys)
|
{
|
p.setWidthHeight(true, true);
|
if (p.getpolystring() != selected.getpolystring() &&
|
(p.min_x >= selected.max_x || Math.Abs(p.min_x - selected.max_x) < 1.5))
|
rects.Add(new FRectangle(p.min_x, p.min_y, p.width, p.height));
|
}
|
float i = 5;
|
bool collide = false;
|
FRectangle nowrect;
|
while (!collide)
|
{
|
nowrect = new FRectangle(selected.min_x + i, selected.min_y, selected.width, selected.height);
|
foreach (FRectangle r in rects)
|
{
|
if (Functions.hassameArea(r, nowrect))
|
{
|
collide = true;
|
i = r.X - selected.max_x;
|
break;
|
}
|
}
|
if (selected.max_x + i > this.Width - Setting.RightWidth)
|
{
|
collide = true;
|
i = this.Width - selected.max_x - Setting.RightWidth;
|
}
|
if (!collide)
|
i += 5;
|
}
|
|
if (i != 0)
|
{
|
selected.move(i, 0);
|
if (selected.Contains.Count > 1)
|
{
|
foreach (Polygon o in selected.Contains)
|
{
|
if (o.temp_number == 0)
|
o.dxfpoly.Move(i, 0);
|
}
|
}
|
else if (selected.temp_number == 0)
|
selected.dxfpoly.Move(i, 0);
|
setRemains();
|
SetCutlines();
|
}
|
}
|
}
|
public void PolyUp(Polygon selected)
|
{
|
if (selected != null)
|
{
|
if (selected.parent != null)
|
selected = selected.parent;
|
selected.setWidthHeight(false, true);
|
List<FRectangle> rects = new List<FRectangle>();
|
foreach (Polygon p in this.polys)
|
{
|
p.setWidthHeight(true, true);
|
if (p.getpolystring() != selected.getpolystring() &&
|
(p.max_y <= selected.min_y || Math.Abs(p.max_y - selected.min_y) < 1.5))
|
rects.Add(new FRectangle(p.min_x, p.min_y, p.width, p.height));
|
}
|
float i = 5;
|
bool collide = false;
|
FRectangle nowrect;
|
while (!collide)
|
{
|
nowrect = new FRectangle(selected.min_x, selected.min_y - i, selected.width, selected.height);
|
foreach (FRectangle r in rects)
|
{
|
if (Functions.hassameArea(r, nowrect))
|
{
|
collide = true;
|
i = selected.min_y - r.Y - r.Height;
|
break;
|
}
|
}
|
if (selected.min_y - i < Setting.UpHeight)
|
{
|
collide = true;
|
i = selected.min_y - Setting.UpHeight;
|
}
|
if (!collide)
|
i += 5;
|
}
|
|
if (i != 0)
|
{
|
selected.move(0, -i);
|
if (selected.Contains.Count > 1)
|
{
|
foreach (Polygon o in selected.Contains)
|
{
|
if (o.temp_number == 0)
|
o.dxfpoly.Move(0, -i);
|
}
|
}
|
else if (selected.temp_number == 0)
|
selected.dxfpoly.Move(0, -i);
|
setRemains();
|
SetCutlines();
|
}
|
}
|
}
|
public void PolyDown(Polygon selected)
|
{
|
if (selected != null)
|
{
|
if (selected.parent != null)
|
selected = selected.parent;
|
selected.setWidthHeight(false, true);
|
List<FRectangle> rects = new List<FRectangle>();
|
foreach (Polygon p in this.polys)
|
{
|
p.setWidthHeight(true, true);
|
if (p.getpolystring() != selected.getpolystring() &&
|
(p.min_y >= selected.max_y || Math.Abs(p.min_y - selected.max_y) < 1.5))
|
rects.Add(new FRectangle(p.min_x, p.min_y, p.width, p.height));
|
}
|
float i = 5;
|
bool collide = false;
|
FRectangle nowrect;
|
while (!collide)
|
{
|
nowrect = new FRectangle(selected.min_x, selected.min_y + i, selected.width, selected.height);
|
foreach (FRectangle r in rects)
|
{
|
if (Functions.hassameArea(r, nowrect))
|
{
|
collide = true;
|
i = r.Y - selected.max_y;
|
break;
|
}
|
}
|
if (selected.max_y + i > this.Height - Setting.DownHeight)
|
{
|
collide = true;
|
i = this.Height - selected.max_y - Setting.DownHeight;
|
}
|
if (!collide)
|
i += 5;
|
}
|
if (i != 0)
|
{
|
selected.move(0, i);
|
if (selected.Contains.Count > 1)
|
{
|
foreach (Polygon o in selected.Contains)
|
{
|
if (o.temp_number == 0)
|
o.dxfpoly.Move(0, i);
|
}
|
}
|
else if (selected.temp_number == 0)
|
selected.dxfpoly.Move(0, i);
|
|
setRemains();
|
SetCutlines();
|
}
|
}
|
}
|
public void PolyDelete(Polygon selected)
|
{
|
Functions.removeSamePoly(polys, selected);
|
setRemains();
|
SetCutlines();
|
}
|
#endregion
|
|
#region ---------------------------版图显示------------------------
|
public Bitmap getbitmapFromPolys(float width, float height, Color stockColor, bool withInfo = true, string[] polystring = null)
|
{
|
|
SetCutOrder(Setting.labelzeroPoint);
|
for (int i = 0; i < this.polys.Count; i++)
|
{
|
|
Polygon finded = Functions.findPolyInList(cutorder, polys[i]);
|
if (finded != null)
|
{
|
polys[i].FenpianShunxu = finded.FenpianShunxu;
|
}
|
else
|
polys[i].FenpianShunxu = 0;
|
}
|
|
|
float ratio = Math.Min(width / (Width + Right + Left), (height) / (Height + Up + Down));
|
if (ratio <= 0)//修复最小化错误
|
return new Bitmap(1, 1);
|
Bitmap paper = new Bitmap((int)(Width * ratio) + 1, (int)((Height) * ratio) + 1);
|
Bitmap realmap = new Bitmap((int)(realwidth * ratio) + 2, (int)(realheight * ratio) + 40 + 2);
|
Graphics g = Graphics.FromImage(paper);
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
if (canbeshowed || Setting.freeEdition == false)
|
{
|
foreach (Polygon poly in polys)
|
{
|
poly.lineWidth = 1;
|
poly.lineColor = directPacking.Setting.polylinecolor;
|
|
}
|
drawPolys(g, ratio, stockColor, withInfo, polystring);
|
//画出余料
|
filterRemains();
|
string s;
|
SizeF size;
|
Pen remainpen = new Pen(Color.DimGray, 1);
|
//remainpen.DashStyle = System.Drawing.Drawing2D.DashStyle.Custom;
|
//remainpen.DashPattern = new float[] { 5, 5 };
|
for (int i = 0; i < remains.Count; i++)
|
{
|
Font fontyuliao = new System.Drawing.Font("宋体", 0.6f * marryFontSize(Math.Min((int)(ratio * remains[i].Width), (int)(ratio * remains[i].Height))));
|
Rectangle ratiorect = new Rectangle((int)(remains[i].X * ratio), (int)(remains[i].Y * ratio), (int)(remains[i].Width * ratio), (int)(remains[i].Height * ratio));
|
g.DrawRectangle(remainpen, ratiorect);
|
//如果余料太小就不写信息,看不清
|
if (Math.Min(remains[i].Width, remains[i].Height) >= 150)
|
{
|
s = Functions.decimalconvert(remains[i].Width) + "," + Functions.decimalconvert(remains[i].Height);
|
Font font2 = new Font("黑体", marryFontSizeString(ratio, s, remains[i].Width, remains[i].Height) * 2f, FontStyle.Bold);
|
// 写余料位置
|
|
if (remains[i].key != "")
|
{
|
size = g.MeasureString("Y" + remains[i].key, font2);
|
g.DrawString("Y" + remains[i].key, font2, new SolidBrush(Color.DimGray),
|
(int)(ratiorect.X + (ratiorect.Width - size.Width) / 2), (int)(ratiorect.Y + +(ratiorect.Height - size.Height) / 2));
|
}
|
|
size = g.MeasureString(((int)remains[i].Width).ToString(), font2);
|
g.DrawString(((int)remains[i].Width).ToString(), font2, new SolidBrush(Color.Red), (int)(ratiorect.X + (ratiorect.Width - size.Width)), (int)(ratiorect.Y + ratiorect.Height - 2 * size.Height));
|
size = g.MeasureString(((int)remains[i].Height).ToString(), font2);
|
g.DrawString(((int)remains[i].Height).ToString(), font2, new SolidBrush(Color.Red), (int)(ratiorect.X + (ratiorect.Width - size.Width)), (int)(ratiorect.Y + ratiorect.Height - size.Height));
|
//size = g.MeasureString(s.Split(',')[1], font2);
|
//g.TranslateTransform(ratiorect.X, ratiorect.Y);
|
//g.RotateTransform(-90);
|
// g.DrawString(s.Split(',')[1], font2, new SolidBrush(Color.IndianRed), -(int)(size.Width + (ratiorect.Height - size.Width) / 2), 0);
|
//g.RotateTransform(90);
|
//g.TranslateTransform(-ratiorect.X, -ratiorect.Y);
|
}
|
}
|
|
|
}
|
else
|
{
|
//免费版本提示
|
string s = Sentences.mianfeibanbenjinkechakan;
|
if (Setting.isBlackDog) s = "加密锁已过期";
|
Font f = new Font("宋体", marryFontSizeString(1, s, paper.Width / 2, paper.Height), FontStyle.Bold | FontStyle.Underline);
|
SizeF size = g.MeasureString(s, f);
|
g.DrawString(s, f, new SolidBrush(Color.Indigo), new PointF((paper.Width - size.Width) / 2, (paper.Height - size.Height) / 2));
|
}
|
g = Graphics.FromImage(realmap);
|
System.Drawing.Drawing2D.HatchBrush brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.DottedDiamond, stockColor, Color.WhiteSmoke);
|
g.FillRectangle(brush, 0, 0, (int)(ratio * realwidth), (int)(ratio * realheight));
|
Rectangle rect = new Rectangle((int)(Left * ratio - 1), (int)(Up * ratio - 1), paper.Width, paper.Height);
|
g.DrawImage(paper, rect);
|
rect = new Rectangle(0, 0, (int)(realwidth * ratio), (int)(realheight * ratio));
|
g.DrawRectangle(Pens.Black, rect);
|
return realmap;
|
}
|
|
#endregion
|
|
#region------------------------------成品明细和优化报告--------------------------
|
|
public float marryFontSizeString(double ratio, string info, double width, double height)
|
{
|
double length = Math.Min(width, height);
|
float size = (float)((length * ratio / info.Length));
|
return size / (float)1.1;
|
}
|
public Dictionary<string, int> getpolydic()
|
{
|
Dictionary<string, int> result = new Dictionary<string, int>();
|
foreach (Polygon p in expandPolys())
|
{
|
if (result.Keys.Contains(p.getMergeInfo()))
|
result[p.getMergeInfo()]++;
|
else
|
result.Add(p.getMergeInfo(), 1);
|
}
|
return result;
|
}
|
public string getInfoString()
|
{
|
return Math.Round(Math.Max(Width, Height), 2) + "," + Math.Round(Math.Min(Width, Height), 2) + "," + Left + "," + Right + "," + Up + "," + Down + "," + wuliaodaima.Trim();
|
}
|
|
/// <summary>
|
/// 转换stock的原点位置
|
/// </summary>
|
/// <param name="originpoint">原来原点位置</param>
|
/// <param name="nextpoint">转换后原点位置</param>
|
private void ChangeZeroPoint(int originpoint, int nextpoint)
|
{
|
if (originpoint == nextpoint)
|
return;
|
switch (originpoint)
|
{
|
case 0://左下
|
{
|
switch (nextpoint)
|
{
|
case 1://左上
|
{
|
this.Y_Mirror();
|
break;
|
}
|
case 2://右下
|
{
|
this.X_Mirror();
|
break;
|
}
|
case 3://右上
|
{
|
this.X_Mirror();
|
this.Y_Mirror();
|
break;
|
}
|
}
|
break;
|
}
|
case 1://左上
|
{
|
switch (nextpoint)
|
{
|
case 0://左下
|
{
|
this.Y_Mirror();
|
break;
|
}
|
case 2://右下
|
{
|
this.X_Mirror();
|
this.Y_Mirror();
|
break;
|
}
|
case 3://右上
|
{
|
this.X_Mirror();
|
break;
|
}
|
}
|
break;
|
}
|
case 2://右下
|
{
|
switch (nextpoint)
|
{
|
case 0://左下
|
{
|
this.X_Mirror();
|
break;
|
}
|
case 1://左上
|
{
|
this.X_Mirror();
|
this.Y_Mirror();
|
break;
|
}
|
case 3://右上
|
{
|
this.Y_Mirror();
|
break;
|
}
|
}
|
break;
|
}
|
case 3://右上
|
{
|
switch (nextpoint)
|
{
|
case 0://左下
|
{
|
this.X_Mirror();
|
this.Y_Mirror();
|
break;
|
}
|
case 1://左上
|
{
|
this.X_Mirror();
|
break;
|
}
|
case 2://右下
|
{
|
this.Y_Mirror();
|
break;
|
}
|
}
|
break;
|
}
|
}
|
}
|
/// <summary>
|
///
|
/// </summary>
|
/// <param name="g"></param>
|
/// <param name="rect"></param>
|
/// <param name="index"></param>
|
/// <param name="pieceinfo">0-不写,1-左边,2-下面</param>
|
public void drawOptInfo(Graphics g, FRectangle rect, int index, int pieceinfo)
|
{
|
// ChangeZeroPoint(Setting.zeroPoint, Setting.PrintZeroPoint);
|
Bitmap map;
|
string info = (index + 1) + "/" + pack.mergedstocks.Count + " " +
|
Functions.decimalconvert(realwidth) + "×" + Functions.decimalconvert(realheight) + "×" + sameCount
|
+ " " + Functions.decimalconvert(get_usage() * 100) + "% L" + Left + "T" + Up + "R" + Right + "B" + Down;
|
Font font = new Font("宋体", 30);
|
SizeF size = g.MeasureString(info, font);
|
|
if (pieceinfo == 1)
|
{
|
double picratio = 0.7;
|
float mapwidth = (float)(rect.Width * picratio);
|
while (size.Width > mapwidth)
|
{
|
font = new Font("宋体", font.Size - 1);
|
size = g.MeasureString(info, font);
|
}
|
map = getWhitebitmapFromPolys(mapwidth, (float)(rect.Height - size.Height - 12));
|
g.DrawString(info, font, new SolidBrush(Color.Black), rect.X + 20, rect.Y + 2);
|
g.DrawImage(map, rect.X + 20, rect.Y + 2 + size.Height + 8);
|
//写最左边的成品信息
|
Dictionary<int, string> infos = getOPTreportInfo();
|
font = new Font("宋体", font.Size - 1);
|
string maxinfo = "";
|
foreach (int key in infos.Keys)
|
if (infos[key].Length > maxinfo.Length)
|
maxinfo = infos[key];
|
size = g.MeasureString(maxinfo, font);
|
|
while (size.Height * 2 * infos.Keys.Count > rect.Height || size.Width > rect.Width - map.Width - 20)
|
{
|
font = new Font("宋体", font.Size - 1);
|
size = g.MeasureString(maxinfo, font);
|
size.Height -= 10;
|
}
|
int index2 = 0;
|
foreach (int key in infos.Keys)
|
{
|
g.DrawString(key.ToString() + ":" + infos[key], font, new SolidBrush(Color.Black), new PointF(rect.X + 20 + map.Width, rect.Y + 60 + index2 * 1 * size.Height));
|
// g.DrawString(infos[key], font, new SolidBrush(Color.Black), new PointF(rect.X + 20 + map.Width, rect.Y +60+ index2 * 2 * size.Height + size.Height));
|
index2++;
|
}
|
}
|
else if (pieceinfo == 2)
|
{
|
float mapwidth = (float)(rect.Width - 40);
|
double picratio = 0.9;
|
while (size.Width > mapwidth)
|
{
|
font = new Font("宋体", font.Size - 1);
|
size = g.MeasureString(info, font);
|
}
|
g.DrawString(info, font, new SolidBrush(Color.Black), (int)(0.05 * rect.Width + 20), rect.Y + 2);
|
|
float mapheight = rect.Height - size.Height - 13;
|
map = getWhitebitmapFromPolys(mapwidth, (float)(mapheight * picratio));
|
g.DrawImage(map, rect.X + (int)(0.05 * rect.Width + 20), rect.Y + size.Height + 8);
|
|
Dictionary<int, string> infos = getOPTreportInfo();
|
font = new Font("宋体", font.Size - 1);
|
string maxinfo = "";
|
foreach (int key in infos.Keys)
|
if ((key + ":" + infos[key]).Length > maxinfo.Length)
|
maxinfo = key + " " + infos[key];
|
SizeF size2 = g.MeasureString(maxinfo, font);
|
size2.Height -= 10;
|
while ((int)((rect.Height - size.Height - 8 - map.Height) / size2.Height) * (int)((rect.Width - 30) / (size2.Width + 5)) < infos.Count)
|
{
|
font = new Font("宋体", font.Size - 1);
|
size2 = g.MeasureString(maxinfo, font);
|
size2.Height -= 10;
|
}
|
int col = (int)((rect.Width - 30) / (size2.Width + 5));
|
|
|
int index2 = 0;
|
foreach (int key in infos.Keys)
|
{
|
g.DrawString(key + ":" + infos[key], font, new SolidBrush(Color.Black),
|
new PointF(rect.X + 20 + (index2 % col) * (size2.Width + 5),
|
rect.Y + size.Height + 8 + map.Height + index2 / col * size2.Height));
|
index2++;
|
}
|
}
|
else
|
{
|
float mapwidth = (float)(rect.Width - 40);
|
while (size.Width > mapwidth)
|
{
|
font = new Font("宋体", font.Size - 1);
|
size = g.MeasureString(info, font);
|
}
|
map = getWhitebitmapFromPolys(mapwidth, (float)(rect.Height - size.Height - 18));
|
g.DrawString(info, font, new SolidBrush(Color.Black), rect.X + (rect.Width - map.Width) / 2, rect.Y + 2);
|
g.DrawImage(map, rect.X + (rect.Width - map.Width) / 2, rect.Y + 2 + size.Height + 12);
|
}
|
// ChangeZeroPoint(Setting.PrintZeroPoint, Setting.zeroPoint);
|
}
|
public void drawYuliaoInfo(Graphics g, FRectangle rect, int index)
|
{
|
//ChangeZeroPoint(Setting.zeroPoint, Setting.PrintZeroPoint);
|
Bitmap map;
|
string info = "第" + (stockNumber + 1) + "版 " + "第" + (index + 1) + "片 " +
|
Functions.decimalconvert(realwidth) + "×" + Functions.decimalconvert(realheight);
|
Font font = new Font("宋体", 40);
|
SizeF size = g.MeasureString(info, font);
|
|
|
float mapwidth = (float)(rect.Width - 40);
|
while (size.Width > mapwidth)
|
{
|
font = new Font("宋体", font.Size - 1);
|
size = g.MeasureString(info, font);
|
}
|
map = getWhitebitmapFromPolys(mapwidth, (float)(rect.Height - size.Height - 18));
|
g.DrawString(info, font, new SolidBrush(Color.Black), rect.X + (rect.Width - map.Width) / 2, rect.Y + 2);
|
g.DrawImage(map, rect.X + (rect.Width - map.Width) / 2, rect.Y + 2 + size.Height + 6);
|
//ChangeZeroPoint(Setting.PrintZeroPoint, Setting.zeroPoint);
|
}
|
public Dictionary<int, string> getOPTreportInfo()
|
{
|
Dictionary<int, string> result = new Dictionary<int, string>();
|
int count;
|
|
foreach (Polygon p in this.expandPolys())
|
{
|
if (result.Keys.Contains(p.rownumber))
|
{
|
count = Convert.ToInt32(result[p.rownumber].Split('=')[1]);
|
result[p.rownumber] = result[p.rownumber].Substring(0, result[p.rownumber].LastIndexOf("=") + 1) + (count + sameCount).ToString();
|
}
|
else
|
{
|
p.setWidthHeight(false, true);
|
result.Add(p.rownumber, Functions.decimalconvert(Math.Max(p.realwidth, p.realheight)) + "×" +
|
Functions.decimalconvert(Math.Min(p.realwidth, p.realheight)) + "=" + sameCount);
|
}
|
}
|
return result;
|
}
|
private void drawWhitePolys(Graphics g, float ratio, bool withInfo = true)
|
{
|
System.Drawing.Drawing2D.HatchBrush brush;
|
// 按比例绘制
|
brush = new System.Drawing.Drawing2D.HatchBrush(System.Drawing.Drawing2D.HatchStyle.DottedDiamond, Color.DarkGray, Color.White);
|
g.FillRectangle(brush, 0, 0, (int)(ratio * Width), (int)(ratio * Height));
|
foreach (Polygon poly in polys)
|
{
|
if (poly.originpoly != null)
|
poly.originpoly.ironrack = poly.ironrack;
|
poly.draw(g, ratio, true, true, null, false);
|
}
|
}
|
public bool hasYuliao()
|
{
|
foreach (FRectangle r in remains)
|
if (r.key != "")
|
return true;
|
return false;
|
}
|
public Bitmap getWhitebitmapFromPolys(float width, float height)
|
{
|
float ratio = 0.9f * Math.Min(width / (Width + Right + Left), (height) / (Height + Up + Down));
|
if (ratio <= 0)//修复最小化错误
|
return new Bitmap(1, 1);
|
Bitmap paper = new Bitmap((int)(Width * ratio) + 2, (int)((Height) * ratio) + 2);
|
Graphics g = Graphics.FromImage(paper);
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
|
if (canbeshowed)
|
{
|
foreach (Polygon poly in polys)
|
{
|
poly.lineWidth = 1;
|
poly.color = Color.White;
|
poly.lineColor = Color.Black;
|
}
|
drawWhitePolys(g, ratio, true);
|
//画出余料
|
List<Color> color = new List<Color> {Color.FromArgb (150, Color.GreenYellow),Color.FromArgb (150, Color.Pink)
|
,Color.FromArgb (150, Color.Purple),Color.FromArgb (150, Color.Silver),Color.FromArgb (150, Color.Tomato) };
|
string s;
|
SizeF size;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
Font fontyuliao = new System.Drawing.Font("宋体", 0.8f * marryFontSize(Math.Min((int)(ratio * remains[i].Width), (int)(ratio * remains[i].Height))));
|
if (Math.Min(remains[i].Width, remains[i].Height) >= 30)
|
{
|
Rectangle ratiorect = new Rectangle((int)(remains[i].X * ratio), (int)(remains[i].Y * ratio), (int)(remains[i].Width * ratio), (int)(remains[i].Height * ratio));
|
g.DrawRectangle(new Pen(Color.DimGray, 1f), ratiorect);
|
s = Functions.decimalconvert(remains[i].Width) + "," + Functions.decimalconvert(remains[i].Height);
|
Font font2 = new Font("宋体", marryFontSizeString(ratio, s, remains[i].Width, remains[i].Height) * 1.8f, FontStyle.Bold);
|
if (remains[i].key != "")
|
{
|
size = g.MeasureString("Y" + remains[i].key, font2);
|
g.DrawString("Y" + remains[i].key, font2, new SolidBrush(Color.DimGray),
|
(int)(ratiorect.X + (ratiorect.Width - size.Width) / 2), (int)(ratiorect.Y + +(ratiorect.Height - size.Height) / 2));
|
}
|
|
size = g.MeasureString(s.Split(',')[0], font2);
|
g.DrawString(s.Split(',')[0], font2, new SolidBrush(Color.Black), (int)(ratiorect.X + (ratiorect.Width - size.Width) / 2), (int)(ratiorect.Y + ratiorect.Height - size.Height));
|
|
size = g.MeasureString(s.Split(',')[1], font2);
|
g.TranslateTransform(ratiorect.X, ratiorect.Y);
|
g.RotateTransform(-90);
|
g.DrawString(s.Split(',')[1], font2, new SolidBrush(Color.Black), -(int)(size.Width + (ratiorect.Height - size.Width) / 2), 0);
|
|
g.RotateTransform(90);
|
g.TranslateTransform(-ratiorect.X, -ratiorect.Y);
|
}
|
}
|
//dxf = getDXF(false);
|
//dxf.Move(-Left, -Up);
|
//List<List<EntityObject>> blocks = dxf.getBlocks(3);
|
if (blocks != null)
|
{
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
blocks[i][j].Move(-Left, -Up);
|
blocks[i][j].Draw(g, new Pen(Color.Black, 2), ratio, -1);
|
blocks[i][j].Move(Left, Up);
|
}
|
}
|
}
|
// dxf.Move(Left, Up);
|
}
|
else
|
{
|
string s = Sentences.mianfeibanbenjinkechakan;
|
Font f = new Font("宋体", marryFontSizeString(1, s, paper.Width / 2, paper.Height), FontStyle.Bold | FontStyle.Underline);
|
SizeF size = g.MeasureString(s, f);
|
g.DrawString(s, f, new SolidBrush(Color.Indigo), new PointF((paper.Width - size.Width) / 2, (paper.Height - size.Height) / 2));
|
}
|
g.DrawRectangle(new Pen(Color.Black, 2), 1, 1, realwidth * ratio - 3, realheight * ratio - 3);
|
return paper;
|
}
|
|
public DxfDocument getHVlinesDocByCutOrder()
|
{
|
cutlines = getCutlinesFromPolys(false, true);
|
List<CutLine> lines = cutlines;
|
DxfDocument dxf = new DxfDocument();
|
dxf.ForCut = false;
|
dxf.stock = this;
|
//把线写入图层中
|
foreach (CutLine line in lines)
|
{
|
if (line != null)
|
{
|
if (line.start.Y == line.end.Y && (line.start.Y < Setting.baibian2 || Up + Height - line.start.Y < Setting.baibian2) ||
|
line.start.X == line.end.X && (line.start.X < Setting.baibian2 || Left + Width - line.start.X < Setting.baibian2))
|
continue;
|
Vector2 startpoint = new Vector2(line.start.X, line.start.Y);
|
Vector2 endpoint = new Vector2(line.end.X, line.end.Y);
|
if (Functions.getVector3Length(new Vector3(startpoint.X, startpoint.Y, 1), new Vector3(endpoint.X, endpoint.Y, 1)) > 0.5)
|
{
|
netDxf.Entities.Line DxfLine = new netDxf.Entities.Line(startpoint, endpoint);
|
dxf.AddEntity(DxfLine);
|
}
|
}
|
else
|
continue;
|
}
|
dxf.AddEntity(new Line(new Vector2(Width, 0), new Vector2(Width, Height)));
|
dxf.AddEntity(new Line(new Vector2(0, Height), new Vector2(Width, Height)));
|
dxf.mergeLine();//去重
|
dxf.HVshunxu(false);//显示上从大到小
|
return dxf;
|
}
|
public List<Polygon> cutorder = null;
|
public void SetCutOrder(int labelzero = 0)//控制标签顺序
|
{
|
Setting.FormatIndex = -1;
|
switch (labelzero)
|
{
|
case 0:
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
break;
|
case 1:
|
X_Mirror();
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
X_Mirror();
|
break;
|
case 2:
|
Y_Mirror();
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
Y_Mirror();
|
break;
|
case 3:
|
X_Mirror();
|
Y_Mirror();
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
Y_Mirror();
|
X_Mirror();
|
break;
|
}
|
|
if (cutorder.Count < this.expandedPolys.Count)
|
{
|
List<Polygon> expandedcutorder = new List<Polygon>();
|
foreach (Polygon p in cutorder)
|
{
|
if (p.Contains.Count > 0)
|
{
|
|
for (int i = 0; i <= p.Contains.Count - 1; i++)
|
{
|
p.Contains[i].parent = p;
|
expandedcutorder.Add(p.Contains[i]);
|
}
|
}
|
else
|
expandedcutorder.Add(p);
|
}
|
if (expandedcutorder.Count < expandedPolys.Count)
|
cutorder = expandedPolys;
|
else
|
cutorder = expandedcutorder;
|
foreach (Polygon p in cutorder) p.color = Color.Yellow;
|
}
|
|
|
for (int i = 0; i < cutorder.Count; i++)
|
{
|
Polygon p = cutorder[i];
|
|
if (p.temp_number == 100)
|
{
|
if (p.g > 0) p.width = p.g;
|
if (p.h > 0) p.height = p.h;
|
}
|
if (p.width == 0 || p.height == 0)
|
{
|
p.width = Math.Max(p.realwidth, 0);
|
}
|
}
|
|
for (int i = 0; i < cutorder.Count; i++)
|
cutorder[i].FenpianShunxu = i + 1;
|
|
}
|
|
|
#region 24.12.09 添加
|
/// <summary>
|
/// 24.12.09 添加,控制标签顺序
|
/// </summary>
|
/// <param name="labelzero"></param>
|
public void SetCutOrder2(int labelzero = 0)
|
{
|
Setting.FormatIndex = -1;
|
switch (labelzero)
|
{
|
case 0:
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
break;
|
case 1:
|
X_Mirror();
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
X_Mirror();
|
break;
|
case 2:
|
Y_Mirror();
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
Y_Mirror();
|
break;
|
case 3:
|
X_Mirror();
|
Y_Mirror();
|
Common.cutorderpolys = new List<Polygon>();
|
setColloectInstructs();
|
cutorder = Common.cutorderpolys;
|
Y_Mirror();
|
X_Mirror();
|
break;
|
}
|
|
if (cutorder.Count < this.expandedPolys.Count)
|
{
|
List<Polygon> expandedcutorder = new List<Polygon>();
|
foreach (Polygon p in cutorder)
|
{
|
if (p.Contains.Count > 0)
|
{
|
|
for (int i = 0; i <= p.Contains.Count - 1; i++)
|
{
|
p.Contains[i].parent = p;
|
expandedcutorder.Add(p.Contains[i]);
|
}
|
}
|
else
|
expandedcutorder.Add(p);
|
}
|
if (expandedcutorder.Count < expandedPolys.Count)
|
cutorder = expandedPolys;
|
else
|
cutorder = expandedcutorder;
|
foreach (Polygon p in cutorder) p.color = Color.Yellow;
|
}
|
|
for (int i = 0; i < cutorder.Count; i++)
|
cutorder[i].FenpianShunxu = i + 1;
|
|
}
|
|
#endregion
|
|
#endregion
|
|
#region----------------------------切割线---------------------------------
|
|
public void mergeCutObjects(ref List<EntityObject> objects)
|
{
|
List<EntityObject> mergedobjects = new List<EntityObject>();
|
for (int i = 0; i < objects.Count; i++)
|
{
|
if (!Contained(ref mergedobjects, objects[i])) mergedobjects.Add(objects[i]);
|
}
|
objects = mergedobjects;
|
}
|
public void mergeCutObjects(ref List<Line> objects)
|
{
|
List<Line> mergedobjects = new List<Line>();
|
for (int i = 0; i < objects.Count; i++)
|
{
|
if (!Contained(mergedobjects, objects[i])) mergedobjects.Add(objects[i]);
|
}
|
objects = mergedobjects;
|
}
|
public bool Contained(ref List<EntityObject> objects, EntityObject obj)
|
{
|
for (int i = 0; i < objects.Count; i++)
|
{
|
if (IsSameObject(objects[i], obj) || IsSegementObject(obj, objects[i])) //如果是相同的线,或者是子线段
|
return true;
|
if (IsSegementObject(objects[i], obj))//更新为较长的线段
|
{
|
objects[i] = obj;
|
return true;
|
}
|
}
|
return false;
|
}
|
public bool Contained(List<Line> objects, Line obj)
|
{
|
for (int i = 0; i < objects.Count; i++)
|
if (IsSameObject(objects[i], obj) || IsSegementObject(obj, objects[i])) //如果是相同的线,或者是子线段
|
return true;
|
return false;
|
}
|
public bool IsSameObject(EntityObject object1, EntityObject object2)
|
{
|
if (object1.Type != EntityType.Line || object2.Type != EntityType.Line) return false;
|
if (Math.Abs(object1.StartPoint.X - object2.StartPoint.X) < 0.01 && Math.Abs(object1.StartPoint.Y - object2.StartPoint.Y) < 0.01
|
&& Math.Abs(object1.EndPoint.X - object2.EndPoint.X) < 0.01 && Math.Abs(object1.EndPoint.Y - object2.EndPoint.Y) < 0.01)
|
return true;
|
if (Math.Abs(object1.StartPoint.X - object2.EndPoint.X) < 0.01 && Math.Abs(object1.StartPoint.Y - object2.EndPoint.Y) < 0.01
|
&& Math.Abs(object1.EndPoint.X - object2.StartPoint.X) < 0.01 && Math.Abs(object1.EndPoint.Y - object2.StartPoint.Y) < 0.01)
|
return true;
|
return false;
|
}
|
public bool IsSegementObject(EntityObject object1, EntityObject object2)
|
{
|
if (object1.Type != EntityType.Line || object2.Type != EntityType.Line) return false;
|
CutLine line1 = new CutLine(new point((float)object1.StartPoint.X, (float)object1.StartPoint.Y), new point((float)object1.EndPoint.X, (float)object1.EndPoint.Y));
|
CutLine line2 = new CutLine(new point((float)object2.StartPoint.X, (float)object2.StartPoint.Y), new point((float)object2.EndPoint.X, (float)object2.EndPoint.Y));
|
return Functions.isSegement(line1, line2);
|
|
}
|
|
public List<CutLine> getCutlinesFromPolys(bool withpolyinner, bool withHVlines)
|
{
|
List<CutLine> cutlines = new List<CutLine>();
|
if (withpolyinner)
|
{
|
foreach (Polygon poly in polys)
|
{
|
if (poly.temp_number == 100)
|
{
|
List<CutLine> innerlines = getPolyLine(poly);
|
foreach (CutLine line in innerlines)//poly本身的线段
|
// if (!Functions.isExternalRectangleLine(new Line(new Vector2(line.start.X, line.start.Y), new Vector2(line.end.X, line.end.Y)), poly))
|
cutlines.Add(line);
|
}
|
else
|
{
|
int a = 1;
|
List<CutLine> innerlines = getPolyLine(poly);
|
foreach (CutLine line in innerlines)//poly本身的线段
|
// if (!Functions.isExternalRectangleLine(new Line(new Vector2(line.start.X, line.start.Y), new Vector2(line.end.X, line.end.Y)), poly))
|
cutlines.Add(line);
|
}
|
}
|
}
|
if (withHVlines)
|
{
|
foreach (CutLine line in getRectLine())//外接矩形形成的切割线
|
cutlines.Add(line);
|
}
|
return cutlines;
|
}
|
private List<CutLine> getRectLine()
|
{
|
|
List<FRectangle> rects = getPolysRects(polys);
|
List<CutLine> rectlines = new List<CutLine>();
|
|
for (int i = 0; i < rects.Count; i++)//polys部分的矩形
|
{
|
point topleft = new point((float)rects[i].X, (float)rects[i].Y);
|
point topright = new point((float)(rects[i].X + rects[i].Width), (float)rects[i].Y);
|
point downleft = new point((float)rects[i].X, (float)(rects[i].Y + rects[i].Height));
|
point downright = new point((float)(rects[i].X + rects[i].Width), (float)(rects[i].Y + rects[i].Height));
|
rectlines.Add(new CutLine(topleft, topright));
|
rectlines.Add(new CutLine(topright, downright));
|
rectlines.Add(new CutLine(topleft, downleft));
|
rectlines.Add(new CutLine(downleft, downright));
|
}
|
|
for (int i = 0; i < remains.Count; i++)//remains部分的矩形
|
{
|
point topleft = new point((float)remains[i].X, (float)remains[i].Y);
|
point topright = new point((float)(remains[i].X + remains[i].Width), (float)remains[i].Y);
|
point downleft = new point((float)remains[i].X, (float)(remains[i].Y + remains[i].Height));
|
point downright = new point((float)(remains[i].X + remains[i].Width), (float)(remains[i].Y + remains[i].Height));
|
rectlines.Add(new CutLine(topleft, topright));
|
rectlines.Add(new CutLine(topright, downright));
|
rectlines.Add(new CutLine(topleft, downleft));
|
rectlines.Add(new CutLine(downleft, downright));
|
}
|
return rectlines;
|
}
|
public List<CutLine> getPolyLine(Polygon poly)//poly本身的线段
|
{
|
List<CutLine> polylines = new List<CutLine>();
|
if (poly != null)
|
{
|
if (poly.Contains.Count >= 2)//若是多元组合
|
{
|
foreach (Polygon polygon in poly.Contains)//组合内的每一个的线段都要加入
|
{
|
Functions.AddLineToList(polygon, ref polylines);
|
}
|
}
|
else//单身汉
|
{
|
Functions.AddLineToList(poly, ref polylines);
|
}
|
polylines.AddRange(poly.getExtendLine());//延展成品内部的切割线
|
}
|
for (int i = 0; i < polylines.Count; i++)
|
if (polylines[i] == null)
|
{
|
polylines.RemoveAt(i);
|
i--;
|
}
|
return polylines;
|
}
|
public void SetCutlines(bool withpolyinner = true, bool widthHVlines = true)
|
{
|
cutlines = getCutlinesFromPolys(withpolyinner, widthHVlines);
|
cutlines = Functions.removeStockLine(cutlines, this);
|
}
|
#endregion
|
|
#region-----------------------------余料--------------------------
|
public static List<FRectangle> getPolysRects(List<Polygon> polylist, double ratio = 1.0)
|
{
|
List<FRectangle> reclist = new List<FRectangle>();
|
foreach (Polygon poly in polylist)
|
{
|
poly.setMaxMin(true);
|
reclist.Add(new FRectangle((poly.min_x * ratio), (poly.min_y * ratio),
|
((poly.max_x - poly.min_x) * ratio), ((poly.max_y - poly.min_y) * ratio)));
|
}
|
return reclist;
|
}
|
public FRectangle getPolyRect(Polygon poly, double ratio)
|
{
|
return new FRectangle((poly.min_x * ratio), (poly.min_y * ratio), (poly.width * ratio), (poly.height * ratio));
|
}
|
public void setRemains(double ratio = 1.0)
|
{
|
List<FRectangle> reclist = new List<FRectangle>();
|
foreach (Polygon poly in this.polys)
|
{
|
poly.setMaxMin(true);
|
reclist.Add(new FRectangle((poly.min_x * ratio), (poly.min_y * ratio), ((poly.max_x - poly.min_x) * ratio), ((poly.max_y - poly.min_y) * ratio)));
|
}
|
remains = Remaind.getRemaindRectList(new FRectangle((X * ratio), (Y * ratio), (Width * ratio), (Height * ratio)), reclist);
|
|
}
|
public void splitRemains()
|
{
|
if (Setting.RemainSizes == null || Setting.RemainSizes.Trim() == "") return;
|
List<string> s = Setting.RemainSizes.Split(';').ToList();
|
int i1, i2, l1, l2;
|
FRectangle r, r1, r2;
|
for (int i = 0; i < this.remains.Count; i++)
|
{
|
r = this.remains[i];
|
i1 = Math.Max((int)r.Width, (int)r.Height);
|
i2 = Math.Min((int)r.Width, (int)r.Height);
|
if (!s.Contains(i1 + "," + i2))
|
{
|
foreach (string ss in s)
|
{
|
if (ss == "") continue;
|
l1 = Int32.Parse(ss.Split(',')[0]);
|
l2 = Int32.Parse(ss.Split(',')[1]);
|
if (r.Width >= l1 && r.Height >= l2)
|
{
|
r1 = new FRectangle(r.X, r.Y + l2, r.Width, r.Height - l2);
|
r2 = new FRectangle(r.X + l1, r.Y, r.Width - l1, l2);
|
if (r1.Width > 0 && r1.Height > 0) this.remains.Add(r1);
|
if (r2.Width > 0 && r2.Height > 0) this.remains.Add(r2);
|
r.Width = l1;
|
r.Height = l2;
|
splitRemains();
|
return;
|
}
|
else if (r.Width >= l2 && r.Height >= l1)
|
{
|
r1 = new FRectangle(r.X, r.Y + l1, r.Width, r.Height - l1);
|
r2 = new FRectangle(r.X + l2, r.Y, r.Width - l2, l1);
|
if (r1.Width > 0 && r1.Height > 0) this.remains.Add(r1);
|
if (r2.Width > 0 && r2.Height > 0) this.remains.Add(r2);
|
r.Width = l2;
|
r.Height = l1;
|
splitRemains();
|
return;
|
}
|
}
|
}
|
}
|
}
|
public void filterRemains()
|
{
|
for (int i = 0; i < remains.Count; i++)
|
{
|
if (remains[i].Width < 1 || remains[i].Height < 1)
|
{
|
remains.RemoveAt(i);
|
i--;
|
}
|
}
|
deletedRemainsIndexs = new List<int>();
|
List<string> s = Setting.RemainSizes.Split(';').ToList();
|
int i1, i2;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
i1 = Math.Max((int)remains[i].Width, (int)remains[i].Height);
|
i2 = Math.Min((int)remains[i].Width, (int)remains[i].Height);
|
if (!s.Contains(i1 + "," + i2))
|
{
|
if ((remains[i].Width >= Setting.yuliaoWidth && remains[i].Height >= Setting.yuliaoHeight) ||
|
(remains[i].Width >= Setting.yuliaoHeight && remains[i].Height >= Setting.yuliaoWidth))
|
{
|
continue;
|
}
|
else
|
{
|
deletedRemainsIndexs.Add(i);
|
}
|
}
|
}
|
}
|
private void addRightRemain2List(ref List<int> mergeindexs, bool h, List<int> indexs)
|
{
|
int nowindex = mergeindexs[mergeindexs.Count - 1];
|
if (h)
|
{
|
for (int j = 0; j < indexs.Count; j++)
|
{
|
int i = indexs[j];
|
if (!mergeindexs.Contains(i) && Math.Abs(remains[i].Y - remains[nowindex].Y) < 1 && Math.Abs(remains[i].Height - remains[nowindex].Height) < 1 &&
|
(Math.Abs(remains[i].X - remains[nowindex].X - remains[nowindex].Width) < 1 || Math.Abs(remains[nowindex].X - remains[i].X - remains[i].Width) < 1))
|
{
|
mergeindexs.Add(i);
|
addRightRemain2List(ref mergeindexs, h, indexs);
|
}
|
}
|
}
|
else
|
{
|
for (int j = 0; j < indexs.Count; j++)
|
{
|
int i = indexs[j];
|
if (!mergeindexs.Contains(i) && Math.Abs(remains[i].X - remains[nowindex].X) < 1 && Math.Abs(remains[i].Width - remains[nowindex].Width) < 1 &&
|
(Math.Abs(remains[i].Y - remains[nowindex].Y - remains[nowindex].Height) < 1 || Math.Abs(remains[nowindex].Y - remains[i].Y - remains[i].Height) < 1))
|
{
|
mergeindexs.Add(i);
|
addRightRemain2List(ref mergeindexs, h, indexs);
|
}
|
}
|
}
|
}
|
|
/// <summary>
|
/// 判断是否通刀
|
/// </summary>
|
/// <param name="rect"></param>
|
/// <param name="hlines"></param>
|
/// <param name="vlines"></param>
|
/// <param name="allrects"></param>
|
/// <returns></returns>
|
private bool IsThrough(FRectangle rect, List<CutLine> hlines, List<CutLine> vlines, List<FRectangle> allrects)
|
{
|
foreach (CutLine l in hlines)
|
{
|
if (l.start.Y > rect.Y + 1 && l.start.Y < rect.Y + rect.Height - 1 &&
|
Math.Min(l.start.X, l.end.X) <= rect.X + 1 && Math.Max(l.start.X, l.end.X) >= rect.X + rect.Width - 1)
|
{
|
return IsThrough(new FRectangle(rect.X, rect.Y, rect.Width, (l.start.Y - rect.Y)), hlines, vlines, allrects) &&
|
IsThrough(new FRectangle(Math.Min(l.start.X, l.end.X), l.start.Y, rect.Width, rect.Y + rect.Height - l.start.Y), hlines, vlines, allrects);
|
}
|
}
|
|
foreach (CutLine l in vlines)
|
{
|
if (l.start.X > rect.X + 1 && l.start.X < rect.X + rect.Width - 1 &&
|
Math.Min(l.start.Y, l.end.Y) <= rect.Y + 1 && Math.Max(l.start.Y, l.end.Y) >= rect.Y + rect.Height - 1)
|
{
|
return IsThrough(new FRectangle(rect.X, rect.Y, (l.start.X - rect.X), rect.Height), hlines, vlines, allrects) &&
|
IsThrough(new FRectangle(l.start.X, Math.Min(l.start.Y, l.end.Y), rect.X + rect.Width - l.start.X, rect.Height), hlines, vlines, allrects);
|
}
|
}
|
|
int count = 0;
|
foreach (FRectangle r in allrects)
|
if (Functions.sameArea(r, rect, 5))
|
count++;
|
if (count > 1)
|
return false;
|
else
|
{
|
//int depth = getThick(hlines, vlines);
|
//if (depth > Setting.thickcontrol)
|
// return false;
|
return true;
|
}
|
}
|
|
#endregion
|
|
|
#region --------------------------------版图调整--------------------------------------------
|
private float geterror(FRectangle r, bool H)
|
{
|
if (H)
|
{
|
if (r.Width >= r.realwidth && r.Width - r.realwidth <= Setting.CutError ||
|
r.realwidth >= r.Width && r.realwidth - r.Width <= Setting.CutError2)
|
return r.Width - r.realwidth;
|
else
|
return r.Width - r.realheight;
|
}
|
else
|
{
|
if (r.Height >= r.realheight && r.Height - r.realheight <= Setting.CutError ||
|
r.realheight >= r.Height && r.realheight - r.Height <= Setting.CutError2)
|
return r.Height - r.realheight;
|
else
|
return r.Height - r.realwidth;
|
}
|
}
|
public void AdjustCuterror()
|
{
|
if (!(Setting.isRecPacking && (Setting.CutError > 0 || Setting.CutError2 > 0))) return;
|
List<CutLine> hlines = new List<CutLine>();
|
List<CutLine> vlines = new List<CutLine>();
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
getCutlines(ref hlines, ref vlines, allrects);
|
float polywidth = Width, polyheight = Height;
|
foreach (FRectangle r in remains)
|
{
|
if (r.Height == Height)
|
polywidth = r.X;
|
if (r.Width == Width)
|
polyheight = r.Y;
|
}
|
#region 筛选出横贯穿线并排序
|
List<CutLine> orderedhlines = new List<CutLine>();
|
while (hlines.Count > 0)
|
{
|
float miny = 9999;
|
int index = -1;
|
for (int i = 0; i < hlines.Count; i++)
|
{
|
if ((hlines[i].start.X == 0 && Math.Abs(hlines[i].end.X - polywidth) < 0.3) ||
|
(hlines[i].end.X == 0 && Math.Abs(hlines[i].start.X - polywidth) < 0.3))
|
{
|
if (hlines[i].start.Y < miny)
|
{
|
miny = hlines[i].start.Y;
|
index = i;
|
}
|
}
|
else
|
hlines.RemoveAt(i--);
|
}
|
if (index != -1)
|
{
|
orderedhlines.Add(hlines[index].getCopy());
|
hlines.RemoveAt(index);
|
}
|
}
|
#endregion
|
#region 筛选出纵贯穿线并排序
|
List<CutLine> orderedvlines = new List<CutLine>();
|
while (vlines.Count > 0)
|
{
|
float miny = 9999;
|
int index = -1;
|
for (int i = 0; i < vlines.Count; i++)
|
{
|
if ((vlines[i].start.Y == 0 && Math.Abs(vlines[i].end.Y - polyheight) < 0.3) ||
|
(vlines[i].end.Y == 0 && Math.Abs(vlines[i].start.Y - polyheight) < 0.3))
|
{
|
if (vlines[i].start.X < miny)
|
{
|
miny = vlines[i].start.X;
|
index = i;
|
}
|
}
|
else
|
vlines.RemoveAt(i--);
|
}
|
if (index != -1)
|
{
|
orderedvlines.Add(vlines[index].getCopy());
|
vlines.RemoveAt(index);
|
}
|
}
|
#endregion
|
orderedhlines.Add(new CutLine(0, Height, Width, Height));
|
orderedvlines.Add(new CutLine(Width, 0, Width, Height));
|
#region 判断是否符合横贯穿线调整条件,构造横strips
|
bool H = true;
|
List<Strip2> hstrips = new List<Strip2>();
|
for (int i = 0; i < orderedhlines.Count; i++)
|
{
|
FRectangle region = new FRectangle(0, 0, Width, 0);
|
if (i == 0)
|
{
|
region.Y = 0;
|
region.Height = orderedhlines[i].start.Y;
|
}
|
else
|
{
|
region.Y = orderedhlines[i - 1].start.Y;
|
region.Height = orderedhlines[i].start.Y - orderedhlines[i - 1].start.Y;
|
}
|
Strip2 strip = new Strip2(region);
|
strip.error = 1000;
|
foreach (FRectangle r in allrects)
|
{
|
if (smallrectinbigrect(r, region))
|
{
|
if (Math.Abs(r.Height - region.Height) < 0.5)
|
{
|
if (strip.error == 1000)
|
{
|
strip.error = geterror(r, false);
|
if (strip.error > 0 && strip.error > Setting.CutError ||
|
strip.error < 0 && strip.error < -Setting.CutError2)
|
{
|
H = false; break;
|
}
|
strip.rects.Add(r);
|
}
|
else if (geterror(r, false) != strip.error)
|
{
|
H = false; break;
|
}
|
else
|
{
|
strip.rects.Add(r);
|
}
|
}
|
else
|
{
|
H = false; break;
|
}
|
}
|
}
|
if (H == false)
|
break;
|
if (strip.rects.Count == 0 || strip.error == 1000)
|
{
|
H = false;
|
break;
|
}
|
hstrips.Add(strip);
|
}
|
// 条带数量需大于1个
|
if (H && hstrips.Count > 1)
|
{
|
H = false;
|
//需存在不同公差的条带,否则没有调整意义
|
for (int i = 1; i < hstrips.Count; i++)
|
if (hstrips[i].error != hstrips[0].error)
|
{
|
H = true;
|
break;
|
}
|
}
|
else
|
H = false;
|
#endregion
|
#region 条件满足,进行横向调整
|
if (H)
|
{
|
float totalerror = 0;
|
foreach (Strip2 s in hstrips)
|
totalerror += s.error;
|
totalerror /= hstrips.Count;
|
for (int i = 0; i < hstrips.Count; i++)
|
{
|
float addedvalue = totalerror - hstrips[i].error;
|
for (int j = 0; j < hstrips[i].rects.Count; j++)
|
hstrips[i].rects[j].Height += addedvalue;
|
for (int j = i + 1; j < hstrips.Count; j++)
|
for (int k = 0; k < hstrips[j].rects.Count; k++)
|
hstrips[j].rects[k].Y += addedvalue;
|
}
|
}
|
#endregion
|
#region 判断是否符合横贯穿线调整条件,构造横strips
|
bool V = true;
|
List<Strip2> vstrips = new List<Strip2>();
|
for (int i = 0; i < orderedvlines.Count; i++)
|
{
|
FRectangle region = new FRectangle(0, 0, 0, Height);
|
if (i == 0)
|
{
|
region.X = 0;
|
region.Width = orderedvlines[i].start.X;
|
}
|
else
|
{
|
region.X = orderedvlines[i - 1].start.X;
|
region.Width = orderedvlines[i].start.X - orderedvlines[i - 1].start.X;
|
}
|
Strip2 strip = new Strip2(region);
|
strip.error = 1000;
|
foreach (FRectangle r in allrects)
|
{
|
if (smallrectinbigrect(r, region))
|
{
|
if (Math.Abs(r.Width - region.Width) < 0.5)
|
{
|
if (strip.error == 1000)
|
{
|
strip.error = geterror(r, true);
|
if (strip.error > 0 && strip.error > Setting.CutError ||
|
strip.error < 0 && strip.error < -Setting.CutError2)
|
{
|
H = false; break;
|
}
|
strip.rects.Add(r);
|
}
|
else if (geterror(r, true) != strip.error)
|
{
|
V = false; break;
|
}
|
else
|
{
|
strip.rects.Add(r);
|
}
|
}
|
else
|
{
|
V = false; break;
|
}
|
}
|
}
|
if (V == false)
|
break;
|
if (strip.rects.Count == 0 || strip.error == 1000)
|
{
|
V = false;
|
break;
|
}
|
vstrips.Add(strip);
|
}
|
// 条带数量需大于1个
|
if (V && vstrips.Count > 1)
|
{
|
V = false;
|
//需存在不同公差的条带,否则没有调整意义
|
for (int i = 1; i < vstrips.Count; i++)
|
if (vstrips[i].error != vstrips[0].error)
|
{
|
V = true;
|
break;
|
}
|
}
|
else
|
V = false;
|
#endregion
|
#region 条件满足,进行横向调整
|
if (V)
|
{
|
float totalerror = 0;
|
foreach (Strip2 s in hstrips)
|
totalerror += s.error;
|
totalerror /= vstrips.Count;
|
for (int i = 0; i < vstrips.Count; i++)
|
{
|
float addedvalue = totalerror - vstrips[i].error;
|
for (int j = 0; j < vstrips[i].rects.Count; j++)
|
vstrips[i].rects[j].Width += addedvalue;
|
for (int j = i + 1; j < vstrips.Count; j++)
|
for (int k = 0; k < vstrips[j].rects.Count; k++)
|
vstrips[j].rects[k].X += addedvalue;
|
}
|
}
|
#endregion
|
}
|
public bool mergeUP(int index = -1)
|
{
|
if (index == -1)
|
{
|
bool merge = true;
|
while (merge)
|
{
|
merge = false;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
for (int j = 0; j < remains.Count; j++)
|
{
|
if (i == j) continue;
|
if (Math.Abs(remains[i].Y + remains[i].Height - remains[j].Y) < 1 &&
|
(Math.Abs(remains[j].X - remains[i].X) < 1 || remains[j].X <= remains[i].X) &&
|
(Math.Abs(remains[j].X + remains[j].Width - remains[i].X - remains[i].Width) < 1 || remains[j].X + remains[j].Width >= remains[i].X + remains[i].Width))
|
{
|
FRectangle clone = remains[j].getcopy();
|
remains[i].Height += remains[j].Height;
|
FRectangle newremain1 = new FRectangle(clone.X, clone.Y, remains[i].X - clone.X, clone.Height);
|
FRectangle newremain2 = new FRectangle(remains[i].X + remains[i].Width, clone.Y, remains[j].X + remains[j].Width - remains[i].X - remains[i].Width, clone.Height);
|
if (newremain1.Width >= 1) remains.Add(newremain1);
|
if (newremain2.Width >= 1) remains.Add(newremain2);
|
remains.RemoveAt(j);
|
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
List<CutLine> hlines = new List<CutLine>(); List<CutLine> vline = new List<CutLine>();
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
if (j < i)
|
remains[i - 1].Height -= clone.Height;
|
else
|
remains[i].Height -= clone.Height;
|
if (newremain1.Width >= 1) remains.Remove(newremain1);
|
if (newremain2.Width >= 1) remains.Remove(newremain2);
|
remains.Insert(j, clone);
|
}
|
else
|
{
|
merge = true;
|
break;
|
}
|
}
|
}
|
if (merge) break;
|
}
|
}
|
}
|
else
|
{
|
for (int j = 0; j < remains.Count; j++)
|
{
|
if (index == j) continue;
|
if (Math.Abs(remains[index].Y + remains[index].Height - remains[j].Y) < 1 &&
|
(Math.Abs(remains[j].X - remains[index].X) < 1 || remains[j].X <= remains[index].X) &&
|
(Math.Abs(remains[j].X + remains[j].Width - remains[index].X - remains[index].Width) < 1 || remains[j].X + remains[j].Width >= remains[index].X + remains[index].Width))
|
{
|
FRectangle clone = remains[j].getcopy();
|
remains[index].Height += remains[j].Height;
|
FRectangle newremain1 = new FRectangle(clone.X, clone.Y, remains[index].X - clone.X, clone.Height);
|
FRectangle newremain2 = new FRectangle(remains[index].X + remains[index].Width, clone.Y, remains[j].X + remains[j].Width - remains[index].X - remains[index].Width, clone.Height);
|
if (newremain1.Width >= 1) remains.Add(newremain1);
|
if (newremain2.Width >= 1) remains.Add(newremain2);
|
remains.RemoveAt(j);
|
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
List<CutLine> hlines = new List<CutLine>(); List<CutLine> vline = new List<CutLine>();
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
if (j < index)
|
remains[index - 1].Height -= clone.Height;
|
else
|
remains[index].Height -= clone.Height;
|
if (newremain1.Width >= 1) remains.Remove(newremain1);
|
if (newremain2.Width >= 1) remains.Remove(newremain2);
|
remains.Insert(j, clone);
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
}
|
}
|
return false;
|
}
|
public bool mergeRight(int index = -1)
|
{
|
if (index == -1)
|
{
|
bool merge = true;
|
while (merge)
|
{
|
merge = false;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
for (int j = 0; j < remains.Count; j++)
|
{
|
if (i == j) continue;
|
if (Math.Abs(remains[i].X + remains[i].Width - remains[j].X) < 1 &&
|
(Math.Abs(remains[j].Y - remains[i].Y) < 1 || remains[j].Y <= remains[i].Y) &&
|
(Math.Abs(remains[j].Y + remains[j].Height - remains[i].Y - remains[i].Height) < 1 || remains[j].Y + remains[j].Height >= remains[i].Y + remains[i].Height))
|
{
|
FRectangle clone = remains[j].getcopy();
|
remains[i].Width += remains[j].Width;
|
FRectangle newremain1 = new FRectangle(clone.X, clone.Y, clone.Width, remains[i].Y - clone.Y);
|
FRectangle newremain2 = new FRectangle(clone.X, remains[i].Y + remains[i].Height, clone.Width, remains[j].Y + remains[j].Height - remains[i].Y - remains[i].Height);
|
if (newremain1.Height >= 1) remains.Add(newremain1);
|
if (newremain2.Height >= 1) remains.Add(newremain2);
|
remains.RemoveAt(j);
|
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
List<CutLine> hlines = new List<CutLine>(); List<CutLine> vline = new List<CutLine>();
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
if (j < i)
|
remains[i - 1].Width -= clone.Width;
|
else
|
remains[i].Width -= clone.Width;
|
if (newremain1.Height >= 1) remains.Remove(newremain1);
|
if (newremain2.Height >= 1) remains.Remove(newremain2);
|
remains.Insert(j, clone);
|
}
|
else
|
{
|
merge = true;
|
break;
|
}
|
}
|
}
|
if (merge) break;
|
}
|
}
|
}
|
else
|
{
|
for (int j = 0; j < remains.Count; j++)
|
{
|
if (index == j) continue;
|
if (Math.Abs(remains[index].X + remains[index].Width - remains[j].X) < 1 &&
|
(Math.Abs(remains[j].Y - remains[index].Y) < 1 || remains[j].Y <= remains[index].Y) &&
|
(Math.Abs(remains[j].Y + remains[j].Height - remains[index].Y - remains[index].Height) < 1 || remains[j].Y + remains[j].Height >= remains[index].Y + remains[index].Height))
|
{
|
FRectangle clone = remains[j].getcopy();
|
remains[index].Width += remains[j].Width;
|
FRectangle newremain1 = new FRectangle(clone.X, clone.Y, clone.Width, remains[index].Y - clone.Y);
|
FRectangle newremain2 = new FRectangle(clone.X, remains[index].Y + remains[index].Height, clone.Width, remains[j].Y + remains[j].Height - remains[index].Y - remains[index].Height);
|
if (newremain1.Height >= 1) remains.Add(newremain1);
|
if (newremain2.Height >= 1) remains.Add(newremain2);
|
remains.RemoveAt(j);
|
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
List<CutLine> hlines = new List<CutLine>(); List<CutLine> vline = new List<CutLine>();
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
if (j < index)
|
remains[index - 1].Width -= clone.Width;
|
else
|
remains[index].Width -= clone.Width;
|
if (newremain1.Height >= 1) remains.Remove(newremain1);
|
if (newremain2.Height >= 1) remains.Remove(newremain2);
|
remains.Insert(j, clone);
|
return false;
|
}
|
else
|
{
|
return true;
|
}
|
}
|
}
|
}
|
return false;
|
}
|
public void mergeUPRight()
|
{
|
bool merge = true;
|
while (merge)
|
{
|
merge = false;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
if (Math.Abs(remains[i].Y + remains[i].Height - this.Height) < 1)//左边的高顶着
|
{
|
for (int j = 0; j < remains.Count; j++)
|
{
|
if (i == j) continue;
|
if (Math.Abs(remains[j].Y + remains[j].Height - this.Height) < 1 &&//右边的高顶着
|
Math.Abs(remains[i].X + remains[i].Width - remains[j].X) < 1 &&//左右衔接
|
remains[j].Height > remains[i].Height &&//右边比左边高
|
(remains[i].Height > remains[i].Width || remains[j].Height > remains[j].Width))//至少有一个是长条形的
|
{
|
//并且要么左边右边的的很窄,要么左边的面积大
|
if (remains[i].Width < 50 || remains[j].Width < 50 || remains[i].Width * remains[i].Height >= remains[j].Width * (remains[j].Height - remains[i].Height))
|
{
|
remains[i].Width += remains[j].Width;
|
remains[j].Height -= remains[i].Height;
|
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
List<CutLine> hlines = new List<CutLine>(); List<CutLine> vline = new List<CutLine>();
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
remains[i].Width -= remains[j].Width;
|
remains[j].Height += remains[i].Height;
|
}
|
else
|
merge = true;
|
}
|
}
|
}
|
}
|
}
|
}
|
}
|
public void movedown()
|
{
|
bool move = true;
|
List<FRectangle> allrects;
|
List<CutLine> hlines = new List<CutLine>();
|
List<CutLine> vline = new List<CutLine>();
|
while (move)
|
{
|
mergeRight();//向右合并
|
move = false;
|
for (int i = 0; i < rects.Count; i++)
|
for (int j = 0; j < remains.Count; j++)
|
{
|
if (Math.Abs(rects[i].X - remains[j].X) < 1 && Math.Abs(rects[i].Y - remains[j].Y - remains[j].Height) < 1)
|
{
|
FRectangle newremain = new FRectangle(remains[j].X + rects[i].Width, remains[j].Y, remains[j].Width - rects[i].Width, remains[j].Height);
|
rects[i].Y -= remains[j].Height;
|
remains[j].Y += rects[i].Height;
|
remains[j].Width = rects[i].Width;
|
if (newremain.Width >= 1) remains.Add(newremain);
|
|
allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
rects[i].Y += remains[j].Height;
|
remains[j].Y -= rects[i].Height;
|
remains[j].Width += newremain.Width;
|
if (newremain.Width >= 1) remains.Remove(newremain);
|
}
|
else
|
move = true;
|
}
|
}
|
}
|
}
|
//去除小于掰边距的余料
|
public void removeminiremain()
|
{
|
bool merge = true;
|
while (merge)
|
{
|
merge = false;
|
for (int i = 0; i < remains.Count; i++)
|
{
|
if (remains[i].Height < Setting.baibian)
|
{
|
merge = mergeUP(i);
|
}
|
else if (remains[i].Width < Setting.baibian)
|
{
|
merge = mergeRight(i);
|
}
|
}
|
}
|
}
|
public void CreateSameWidthRemains()
|
{
|
bool created = true;
|
while (created)
|
{
|
created = false;
|
for (int i = 0; i < rects.Count; i++)
|
{
|
FRectangle r = rects[i];
|
for (int j = 0; j < remains.Count; j++)
|
{
|
FRectangle remain = remains[j];
|
if (Math.Abs(r.Y + r.Height - remain.Y) < 1 &&
|
(Math.Abs(r.X - remain.X) < 1 || remain.X <= r.X) &&
|
(Math.Abs(r.X + r.Width - remain.X - remain.Width) < 1 || remain.X + remain.Width >= r.X + r.Height))
|
{
|
FRectangle newremain1 = new FRectangle(r.X + r.Width, remain.Y, remain.X + remain.Width - r.X - r.Width, remain.Height);
|
FRectangle newremian2 = new FRectangle(remain.X, remain.Y, r.X - remain.X, remain.Height);
|
remains[j] = new FRectangle(r.X, remain.Y, r.Width, remain.Height);
|
if (newremain1.Width >= 1)
|
{
|
remains.Add(newremain1);
|
created = true;
|
}
|
if (newremian2.Width >= 1)
|
{
|
remains.Add(newremian2);
|
created = true;
|
}
|
break;
|
}
|
}
|
}
|
}
|
}
|
public void CreateSameHeightRemains()
|
{
|
bool merge = true;
|
while (merge)
|
{
|
mergeUP();
|
merge = false;
|
for (int i = 0; i < rects.Count; i++)
|
{
|
FRectangle r = rects[i];
|
for (int j = 0; j < remains.Count; j++)
|
{
|
FRectangle remain = remains[j];
|
if (Math.Abs(r.X - remain.X - remain.Width) < 1 && Math.Abs(remain.Y - r.Y) < 1 && (Math.Abs(remain.Height - r.Height) < 1))
|
{
|
FRectangle remainclone = remain.getcopy();
|
FRectangle newremian = new FRectangle(remain.X, remain.Y + r.Height, remain.Width, remain.Height - r.Height);
|
remain.Height = r.Height;
|
remain.X += r.Width;
|
rects[i].X -= remainclone.Width;
|
if (newremian.Height >= 1) remains.Add(newremian);
|
|
List<FRectangle> allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
List<CutLine> hlines = new List<CutLine>(); List<CutLine> vline = new List<CutLine>();
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
remain.Height = remainclone.Height;
|
remain.X -= r.Width;
|
rects[i].X += remainclone.Width;
|
if (newremian.Height >= 1) remains.Remove(newremian);
|
}
|
else
|
{
|
merge = true;
|
}
|
}
|
}
|
}
|
}
|
}
|
private bool smallrectinbigrect(FRectangle smallrect, FRectangle bigrect)
|
{
|
if ((Math.Abs(smallrect.X - bigrect.X) < 1 || smallrect.X > bigrect.X) &&
|
(Math.Abs(smallrect.Y - bigrect.Y) < 1 || smallrect.Y > bigrect.Y) &&
|
(Math.Abs(smallrect.X + smallrect.Width - bigrect.X - bigrect.Width) < 1 || smallrect.X + smallrect.Width < bigrect.X + bigrect.Width) &&
|
(Math.Abs(smallrect.Y + smallrect.Height - bigrect.Y - bigrect.Height) < 1 || smallrect.Y + smallrect.Height < bigrect.Y + bigrect.Height))
|
return true;
|
return false;
|
}
|
private List<Line> FilterVlinesForShift(FRectangle rect, List<CutLine> vlines)//包含在rect中的竖线
|
{
|
List<Line> result = new List<Line>();
|
for (int i = 0; i < vlines.Count; i++)
|
{
|
double minY = Math.Min(vlines[i].start.Y, vlines[i].end.Y);
|
double maxY = Math.Max(vlines[i].start.Y, vlines[i].end.Y);
|
double lineheight = Math.Abs(vlines[i].start.Y - vlines[i].end.Y);
|
if (Math.Abs(rect.Y - minY) < 160 && Math.Abs(maxY - rect.Y - rect.Height) < 160 && vlines[i].start.X > rect.X && vlines[i].start.X <= rect.X + rect.Width + 1)
|
{
|
result.Add(vlines[i].toEntityLine());
|
}
|
}
|
for (int i = 1; i < result.Count; i++)//反向排序
|
{
|
for (int j = 0; j < result.Count - i; j++)
|
{
|
if (result[j].StartPoint.X > result[j + 1].StartPoint.X)
|
{
|
Line temp = result[j];
|
result[j] = result[j + 1];
|
result[j + 1] = temp;
|
}
|
}
|
}
|
return result;
|
}
|
public void leftrighttrans1()
|
{
|
|
float maxx = 0, maxy = 0;
|
for (int i = 0; i < expandedPolys.Count; i++)
|
{
|
if (expandedPolys[i].X + expandedPolys[i].width > maxx)
|
maxx = expandedPolys[i].X + expandedPolys[i].width;
|
if (expandedPolys[i].Y + expandedPolys[i].height > maxy)
|
maxy = expandedPolys[i].Y + expandedPolys[i].height;
|
}
|
List<Line> interXLines = FilterVlinesForShift(new FRectangle(Left, Down, maxx, maxy), vlines);
|
// List<Line> interXLines = FilterVlinesForShift(new FRectangle(Left, Down, realwidth - Left - Right, realheight - Down - Up), vlines);
|
// if (interXLines2.Count > interXLines.Count) interXLines = interXLines2;
|
if (Left + maxx >= realwidth - Right) interXLines.Add(new Line(new Vector2(Left + maxx, Down), new Vector2(Left + maxx, Down + maxy)));
|
List<Strip> strips = new List<Strip>();
|
for (int i = 0; i < interXLines.Count; i++)
|
{
|
|
Strip strip = new Strip(i);
|
if (i == 0)
|
{
|
strip.x = Left;
|
strip.width = interXLines[0].StartPoint.X - Left;
|
|
}
|
else
|
{
|
strip.x = interXLines[i - 1].StartPoint.X;
|
strip.width = interXLines[i].StartPoint.X - interXLines[i - 1].StartPoint.X;
|
}
|
foreach (Polygon p in expandedPolys)
|
{
|
if (p.X + Left >= strip.x && p.X + p.width + Left <= strip.x + strip.width)
|
strip.polys.Add(p);
|
}
|
strips.Add(strip);
|
}
|
for (int i = 0; i < strips.Count; i++) strips[i].setheight();
|
bool sorted = false;
|
while (!sorted)
|
{
|
sorted = true;
|
for (int i = 0; i < strips.Count - 1; i++)
|
{
|
if (1000 * strips[i].height + strips[i].width < 1000 * strips[i + 1].height + strips[i + 1].width)
|
{
|
Strip temp = strips[i];
|
strips[i] = strips[i + 1];
|
strips[i + 1] = temp;
|
sorted = false;
|
}
|
}
|
}
|
double currentx = Left;
|
if (Setting.isRecPacking)
|
{
|
for (int i = 0; i < strips.Count; i++)
|
{
|
strips[i].xshift = currentx - strips[i].x;
|
foreach (Polygon p in strips[i].polys)
|
{
|
p.move((float)strips[i].xshift, 0);
|
}
|
currentx += strips[i].width;
|
}
|
}
|
}
|
|
public void leftrighttrans()
|
{
|
bool trans = true;
|
bool haspolyup;
|
List<FRectangle> allrects;
|
List<CutLine> hlines = new List<CutLine>();
|
List<CutLine> vline = new List<CutLine>();
|
mergeRemains();
|
mergeUP();
|
CreateSameWidthRemains();
|
while (trans)
|
{
|
trans = false;
|
for (int i = 0; i < rects.Count; i++)
|
for (int j = 0; j < rects.Count; j++)
|
{
|
if (i == j) continue;
|
if (Math.Abs(rects[i].Y - rects[j].Y) < 1 &&
|
Math.Abs(rects[i].X - rects[j].X - rects[j].Width) < 1 &&
|
(rects[i].Height > rects[j].Height ||
|
(rects[i].Height == rects[j].Height && rects[i].Width > rects[j].Width) ||
|
(rects[i].Height == rects[j].Height && rects[i].Width == rects[j].Width && rects[i].rownumber < rects[j].rownumber)))
|
{
|
haspolyup = false;
|
foreach (FRectangle r in rects)
|
if (r.Y >= rects[j].Y + rects[j].Height)
|
{
|
haspolyup = true; break;
|
}
|
|
List<int> remainsi = new List<int>();
|
List<int> remainsj = new List<int>();
|
if (!haspolyup)
|
{
|
for (int k = 0; k < remains.Count; k++)
|
{
|
if (Math.Abs(remains[k].Y - rects[i].Y - rects[i].Height) < 1 &&
|
(Math.Abs(rects[i].X - remains[k].X) < 1 || remains[k].X >= rects[i].X) &&
|
(Math.Abs(rects[i].X + rects[i].Width - remains[k].X - remains[k].Width) < 1 || remains[k].X + remains[k].Width <= rects[i].X + rects[i].Width))
|
{
|
remainsi.Add(k);
|
}
|
else if (Math.Abs(remains[k].Y - rects[j].Y - rects[j].Height) < 1 &&
|
(Math.Abs(rects[j].X - remains[k].X) < 1 || remains[k].X >= rects[j].X) &&
|
(Math.Abs(rects[j].X + rects[j].Width - remains[k].X - remains[k].Width) < 1 || remains[k].X + remains[k].Width <= rects[j].X + rects[j].Width))
|
{
|
remainsj.Add(k);
|
}
|
}
|
|
foreach (int index in remainsi)
|
remains[index].X -= rects[j].Width;
|
foreach (int index in remainsj)
|
remains[index].X += rects[i].Width;
|
}
|
else if (Math.Abs(rects[i].Height - rects[j].Height) >= 0.5)
|
continue;
|
|
rects[i].X -= rects[j].Width;
|
rects[j].X += rects[i].Width;
|
|
allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
rects[i].X += rects[j].Width;
|
rects[j].X -= rects[i].Width;
|
foreach (int index in remainsi)
|
remains[index].X += rects[j].Width;
|
foreach (int index in remainsj)
|
remains[index].X -= rects[i].Width;
|
}
|
else
|
trans = true;
|
}
|
}
|
}
|
}
|
public void updowntrans()
|
{
|
bool trans = true;
|
List<FRectangle> allrects;
|
List<CutLine> hlines = new List<CutLine>();
|
List<CutLine> vline = new List<CutLine>();
|
while (trans)
|
{
|
trans = false;
|
for (int i = 0; i < rects.Count; i++)
|
for (int j = 0; j < rects.Count; j++)
|
{
|
if (i == j) continue;
|
if (Math.Abs(rects[i].X - rects[j].X) < 1 &&
|
Math.Abs(rects[i].Y - rects[j].Y - rects[j].Height) < 1 &&
|
((rects[i].Width == rects[j].Width && rects[i].Height > rects[j].Height) ||
|
(rects[i].Width == rects[j].Width && rects[i].Height == rects[j].Height && rects[i].rownumber > rects[j].rownumber)))
|
{
|
rects[i].Y -= rects[j].Height;
|
rects[j].Y += rects[i].Height;
|
|
allrects = new List<FRectangle>();
|
allrects.AddRange(rects);
|
allrects.AddRange(remains);
|
getCutlines(ref hlines, ref vline, allrects);
|
if (!IsThrough(new FRectangle(0, 0, Width, Height), hlines, vline, allrects))
|
{
|
rects[i].Y += rects[j].Height;
|
rects[j].Y -= rects[i].Height;
|
}
|
else
|
trans = true;
|
}
|
}
|
}
|
}
|
public void mergeRemains()
|
{
|
for (int i = 0; i < remains.Count; i++) {
|
if (remains[i].Width < 1 || remains[i].Height < 1)
|
{
|
remains.RemoveAt(i);
|
i--;
|
}
|
}
|
|
bool merge = true;
|
while (merge)
|
{
|
merge = false;
|
#region 横向的
|
List<int> indexs = new List<int>();
|
for (int i = 0; i < remains.Count; i++)
|
indexs.Add(i);
|
List<int> mergeindexs = new List<int>();
|
List<CutLine> hlines, vlines;
|
List<int> totalindex = new List<int>();
|
while (indexs.Count > 1)
|
{
|
mergeindexs = new List<int>();
|
mergeindexs.Add(indexs[0]);
|
addRightRemain2List(ref mergeindexs, true, indexs);
|
if (mergeindexs.Count >= 2)
|
{
|
List<FRectangle> allrects = new List<FRectangle>();
|
foreach (FRectangle r in rects)
|
allrects.Add(r);
|
for (int i = 0; i < remains.Count; i++)
|
if (!mergeindexs.Contains(i))
|
allrects.Add(remains[i]);
|
float minx = 9999999; float maxx = 0;
|
foreach (int i in mergeindexs)
|
{
|
if (remains[i].X < minx) minx = remains[i].X;
|
if (remains[i].X + remains[i].Width > maxx) maxx = remains[i].X + remains[i].Width;
|
}
|
allrects.Add(new FRectangle(minx, remains[mergeindexs[0]].Y, maxx - minx, remains[mergeindexs[0]].Height));
|
hlines = new List<CutLine>();
|
vlines = new List<CutLine>();
|
getCutlines(ref hlines, ref vlines, allrects);
|
mergeindexs.Sort();//从小到大排序
|
mergeindexs.Reverse();//从大到小
|
if (IsThrough(new FRectangle(0, 0, Width, Height), hlines, vlines, allrects))
|
{
|
remains.Add(new FRectangle(minx, remains[mergeindexs[0]].Y, maxx - minx, remains[mergeindexs[0]].Height));
|
totalindex.AddRange(mergeindexs);
|
merge = true;
|
}
|
foreach (int i in mergeindexs)
|
indexs.Remove(i);
|
}
|
else
|
{
|
indexs.RemoveAt(0);
|
}
|
}
|
totalindex.Sort();//从小到大排序
|
totalindex.Reverse();//从大到小
|
foreach (int i in totalindex)
|
remains.RemoveAt(i);
|
#endregion
|
|
#region 纵向的
|
indexs = new List<int>();
|
for (int i = 0; i < remains.Count; i++)
|
indexs.Add(i);
|
totalindex = new List<int>();
|
while (indexs.Count > 1)
|
{
|
mergeindexs = new List<int>();
|
mergeindexs.Add(indexs[0]);
|
addRightRemain2List(ref mergeindexs, false, indexs);
|
if (mergeindexs.Count >= 2)
|
{
|
List<FRectangle> allrects = new List<FRectangle>();
|
foreach (FRectangle r in rects)
|
allrects.Add(r);
|
for (int i = 0; i < remains.Count; i++)
|
if (!mergeindexs.Contains(i))
|
allrects.Add(remains[i]);
|
float miny = 9999999; float maxy = 0;
|
foreach (int i in mergeindexs)
|
{
|
if (remains[i].Y < miny) miny = remains[i].Y;
|
if (remains[i].Y + remains[i].Height > maxy) maxy = remains[i].Y + remains[i].Height;
|
}
|
allrects.Add(new FRectangle(remains[mergeindexs[0]].X, miny, remains[mergeindexs[0]].Width, maxy - miny));
|
hlines = new List<CutLine>();
|
vlines = new List<CutLine>();
|
getCutlines(ref hlines, ref vlines, allrects);
|
mergeindexs.Sort();//从小到大排序
|
mergeindexs.Reverse();//从大到小
|
if (IsThrough(new FRectangle(0, 0, Width, Height), hlines, vlines, allrects))
|
{
|
remains.Add(new FRectangle(remains[mergeindexs[0]].X, miny, remains[mergeindexs[0]].Width, maxy - miny));
|
totalindex.AddRange(mergeindexs);
|
merge = true;
|
}
|
foreach (int i in mergeindexs)
|
indexs.Remove(i);
|
}
|
else
|
{
|
indexs.RemoveAt(0);
|
}
|
}
|
totalindex.Sort();//从小到大排序
|
totalindex.Reverse();//从大到小
|
foreach (int i in totalindex)
|
remains.RemoveAt(i);
|
|
#endregion
|
}
|
}
|
|
public void mergeRemains_SSQ()
|
{
|
for (int i = 0; i < remains.Count; i++)
|
{
|
if (remains[i].Width < 1 || remains[i].Height < 1)
|
{
|
remains.RemoveAt(i);
|
i--;
|
}
|
}
|
|
bool merge = true;
|
while (merge)
|
{
|
merge = false;
|
#region 横向的
|
List<int> indexs = new List<int>();
|
for (int i = 0; i < remains.Count; i++)
|
indexs.Add(i);
|
List<int> mergeindexs = new List<int>();
|
List<CutLine> hlines, vlines;
|
List<int> totalindex = new List<int>();
|
while (indexs.Count > 1)
|
{
|
mergeindexs = new List<int>();
|
mergeindexs.Add(indexs[0]);
|
addRightRemain2List(ref mergeindexs, true, indexs);
|
if (mergeindexs.Count >= 2)
|
{
|
List<FRectangle> allrects = new List<FRectangle>();
|
foreach (FRectangle r in rects)
|
allrects.Add(r);
|
for (int i = 0; i < remains.Count; i++)
|
if (!mergeindexs.Contains(i))
|
allrects.Add(remains[i]);
|
float minx = 9999999; float maxx = 0;
|
foreach (int i in mergeindexs)
|
{
|
if (remains[i].X < minx) minx = remains[i].X;
|
if (remains[i].X + remains[i].Width > maxx) maxx = remains[i].X + remains[i].Width;
|
}
|
allrects.Add(new FRectangle(minx, remains[mergeindexs[0]].Y, maxx - minx, remains[mergeindexs[0]].Height));
|
hlines = new List<CutLine>();
|
vlines = new List<CutLine>();
|
getCutlines(ref hlines, ref vlines, allrects);
|
mergeindexs.Sort();//从小到大排序
|
mergeindexs.Reverse();//从大到小
|
if (IsThrough(new FRectangle(0, 0, Width, Height), hlines, vlines, allrects))
|
{
|
remains.Add(new FRectangle(minx, remains[mergeindexs[0]].Y, maxx - minx, remains[mergeindexs[0]].Height));
|
totalindex.AddRange(mergeindexs);
|
merge = true;
|
}
|
foreach (int i in mergeindexs)
|
indexs.Remove(i);
|
}
|
else
|
{
|
indexs.RemoveAt(0);
|
}
|
}
|
totalindex.Sort();//从小到大排序
|
totalindex.Reverse();//从大到小
|
foreach (int i in totalindex)
|
remains.RemoveAt(i);
|
#endregion
|
|
#region 纵向的
|
/*indexs = new List<int>();
|
for (int i = 0; i < remains.Count; i++)
|
indexs.Add(i);
|
totalindex = new List<int>();
|
while (indexs.Count > 1)
|
{
|
mergeindexs = new List<int>();
|
mergeindexs.Add(indexs[0]);
|
addRightRemain2List(ref mergeindexs, false, indexs);
|
if (mergeindexs.Count >= 2)
|
{
|
List<FRectangle> allrects = new List<FRectangle>();
|
foreach (FRectangle r in rects)
|
allrects.Add(r);
|
for (int i = 0; i < remains.Count; i++)
|
if (!mergeindexs.Contains(i))
|
allrects.Add(remains[i]);
|
float miny = 9999999; float maxy = 0;
|
foreach (int i in mergeindexs)
|
{
|
if (remains[i].Y < miny) miny = remains[i].Y;
|
if (remains[i].Y + remains[i].Height > maxy) maxy = remains[i].Y + remains[i].Height;
|
}
|
allrects.Add(new FRectangle(remains[mergeindexs[0]].X, miny, remains[mergeindexs[0]].Width, maxy - miny));
|
hlines = new List<CutLine>();
|
vlines = new List<CutLine>();
|
getCutlines(ref hlines, ref vlines, allrects);
|
mergeindexs.Sort();//从小到大排序
|
mergeindexs.Reverse();//从大到小
|
if (IsThrough(new FRectangle(0, 0, Width, Height), hlines, vlines, allrects))
|
{
|
remains.Add(new FRectangle(remains[mergeindexs[0]].X, miny, remains[mergeindexs[0]].Width, maxy - miny));
|
totalindex.AddRange(mergeindexs);
|
merge = true;
|
}
|
foreach (int i in mergeindexs)
|
indexs.Remove(i);
|
}
|
else
|
{
|
indexs.RemoveAt(0);
|
}
|
}
|
totalindex.Sort();//从小到大排序
|
totalindex.Reverse();//从大到小
|
foreach (int i in totalindex)
|
remains.RemoveAt(i);
|
*/
|
#endregion
|
}
|
}
|
|
|
|
public double getMenliaoArea()
|
{
|
double area = 0;
|
foreach (FRectangle r in this.remains)
|
if (r.Width == this.Width ||
|
r.Height == this.Height)
|
area += r.Width * r.Height * Math.Pow(10, -6);
|
return area;
|
}
|
|
/// <summary>
|
/// 获取所有切割线
|
/// </summary>
|
/// <param name="hlines">水平线</param>
|
/// <param name="vlines">垂直线</param>
|
/// <param name="allrects">所有图形得集合</param>
|
private void getCutlines(ref List<CutLine> hlines, ref List<CutLine> vlines, List<FRectangle> allrects)
|
{
|
hlines = new List<CutLine>();
|
vlines = new List<CutLine>();
|
foreach (FRectangle r in allrects)
|
{
|
hlines.Add(new CutLine(r.X, r.Y, r.X + r.Width, r.Y));
|
hlines.Add(new CutLine(r.X, r.Y + r.Height, r.X + r.Width, r.Y + r.Height));
|
vlines.Add(new CutLine(r.X, r.Y, r.X, r.Y + r.Height));
|
vlines.Add(new CutLine(r.X + r.Width, r.Y, r.X + r.Width, r.Y + r.Height));
|
}
|
|
//连接收尾相连得横线段
|
for (int i = 0; i < hlines.Count; i++)
|
{
|
for (int j = 0; j < hlines.Count; j++)
|
{
|
if (i == j || hlines[i].start.Y != hlines[j].start.Y) continue;
|
if (Math.Abs(hlines[i].start.X - hlines[j].end.X) < 1 || Math.Abs(hlines[i].end.X - hlines[j].start.X) < 1)
|
{
|
CutLine newline = new CutLine(Math.Min(Math.Min(hlines[i].start.X, hlines[j].end.X), Math.Min(hlines[i].end.X, hlines[j].start.X)), hlines[i].start.Y,
|
Math.Max(Math.Max(hlines[i].start.X, hlines[j].end.X), Math.Max(hlines[i].end.X, hlines[j].start.X)), hlines[i].start.Y);
|
if (newline.end.X < newline.start.X)
|
{
|
break;
|
}
|
hlines.RemoveAt(Math.Max(i, j));
|
hlines.RemoveAt(Math.Min(i, j));
|
hlines.Add(newline);
|
i = -1;
|
break;
|
}
|
}
|
}
|
|
//去除重叠横线
|
for (int i = 0; i < hlines.Count; i++)
|
{
|
for (int j = 0; j < hlines.Count; j++)
|
{
|
if (i == j || hlines[i].start.Y != hlines[j].start.Y) continue;
|
if (Math.Max(hlines[i].start.X, hlines[i].end.X) >= Math.Max(hlines[j].start.X, hlines[j].end.X) &&
|
Math.Min(hlines[i].start.X, hlines[i].end.X) <= Math.Min(hlines[j].start.X, hlines[j].end.X))
|
{
|
hlines.RemoveAt(j);
|
i = -1;
|
break;
|
}
|
}
|
}
|
|
|
//连接收尾相连垂直线段
|
for (int i = 0; i < vlines.Count; i++)
|
{
|
for (int j = 0; j < vlines.Count; j++)
|
{
|
if (i == j || vlines[i].start.X != vlines[j].start.X) continue;
|
if (Math.Abs(vlines[i].start.Y - vlines[j].end.Y) < 1 || Math.Abs(vlines[i].end.Y - vlines[j].start.Y) < 1)
|
{
|
CutLine newline = new CutLine(vlines[i].start.X, Math.Min(Math.Min(vlines[i].start.Y, vlines[j].end.Y), Math.Min(vlines[i].end.Y, vlines[j].start.Y)),
|
vlines[i].start.X, Math.Max(Math.Max(vlines[i].start.Y, vlines[j].end.Y), Math.Max(vlines[i].end.Y, vlines[j].start.Y)));
|
vlines.RemoveAt(Math.Max(i, j));
|
vlines.RemoveAt(Math.Min(i, j));
|
vlines.Add(newline);
|
i = -1;
|
break;
|
}
|
}
|
}
|
|
//去除重叠得短的线段
|
for (int i = 0; i < vlines.Count; i++)
|
{
|
for (int j = 0; j < vlines.Count; j++)
|
{
|
if (i == j || vlines[i].start.X != vlines[j].start.X) continue;
|
if (Math.Max(vlines[i].start.Y, vlines[i].end.Y) >= Math.Max(vlines[j].start.Y, vlines[j].end.Y) &&
|
Math.Min(vlines[i].start.Y, vlines[i].end.Y) <= Math.Min(vlines[j].start.Y, vlines[j].end.Y))
|
{
|
vlines.RemoveAt(j);
|
i = -1;
|
break;
|
}
|
}
|
}
|
|
//去除和边框重叠得垂直线段
|
for (int i = 0; i < vlines.Count; i++)
|
{
|
if (vlines[i].start.X == 0 || Math.Abs(vlines[i].start.X - Width) < 0.001 || Math.Abs(vlines[i].start.Y - vlines[i].end.Y) < 1)
|
{
|
vlines.RemoveAt(i);
|
i--;
|
}
|
}
|
|
//去除和边框重叠得水平线
|
for (int i = 0; i < hlines.Count; i++)
|
{
|
if (hlines[i].start.Y == 0 || Math.Abs(hlines[i].start.Y - Height) < 0.001 || Math.Abs(hlines[i].start.X - hlines[i].end.X) < 1)
|
{
|
hlines.RemoveAt(i);
|
i--;
|
}
|
}
|
}
|
|
|
public int getCutlineCount()
|
{
|
List<CutLine> hlines = new List<CutLine>();
|
List<CutLine> vlines = new List<CutLine>();
|
List<FRectangle> allrects = new List<FRectangle>();
|
foreach (FRectangle r in rects)
|
allrects.Add(r);
|
//foreach (FRectangle r in remains)
|
// allrects.Add(r);
|
// getCutlines(ref hlines, ref vlines, allrects);
|
|
foreach (FRectangle r in allrects)
|
{
|
hlines.Add(new CutLine(r.X, r.Y, r.X + r.Width, r.Y));
|
hlines.Add(new CutLine(r.X, r.Y + r.Height, r.X + r.Width, r.Y + r.Height));
|
vlines.Add(new CutLine(r.X, r.Y, r.X, r.Y + r.Height));
|
vlines.Add(new CutLine(r.X + r.Width, r.Y, r.X + r.Width, r.Y + r.Height));
|
}
|
vlines = Functions.mergeVlines(vlines);
|
hlines = Functions.mergeHlines(hlines);
|
|
double length = 0;
|
foreach (CutLine line in vlines)
|
length += Math.Abs(line.start.Y - line.end.Y);
|
foreach (CutLine line in hlines)
|
length += Math.Abs(line.start.X - line.end.X);
|
return hlines.Count + vlines.Count + (int)length;
|
}
|
#endregion
|
|
#region -----------------------------DXF与G代码--------------------------------------
|
|
|
public List<List<EntityObject>> blocks;
|
public void CheckSingleDirection(ref List<EntityObject> objects)
|
{
|
if (directPacking.Setting.singleDirectionCutting)//正向切割对斜线也起作用
|
{
|
foreach (EntityObject l in objects)
|
{
|
//if (l.Type == EntityType.Line && l.StartPoint.X == l.EndPoint.X)//竖线
|
//{
|
// if (l.StartPoint.Y < l.EndPoint.Y)
|
// {
|
// netDxf.Vector3 temp = new Vector3();
|
// temp = l.StartPoint;
|
// l.StartPoint = l.EndPoint;
|
// l.EndPoint = temp;
|
// }
|
//}
|
//else
|
if (l.Type == EntityType.Line && l.StartPoint.X > l.EndPoint.X)//斜线
|
{
|
netDxf.Vector3 temp = new Vector3();
|
temp = l.StartPoint;
|
l.StartPoint = l.EndPoint;
|
l.EndPoint = temp;
|
}
|
}
|
}
|
}
|
|
public void setBlocks(bool considerSetting = true)
|
{
|
if (!canbeshowed) return;
|
List<EntityObject> objects = ToCutObjects(true);
|
mergeCutObjects(ref objects);//去重
|
CheckSingleDirection(ref objects);//正向切割
|
DxfDocument dxf = new DxfDocument();
|
foreach (EntityObject o in objects)
|
dxf.AddEntity(o);
|
|
if (Right > 0)//右边线总丢线,不得已强加在这里
|
{
|
Vector2 startpoint2 = new Vector2(realwidth - Right, 0);
|
Vector2 endpoint2 = new Vector2(realwidth - Right, realheight);
|
netDxf.Entities.Line line2 = new netDxf.Entities.Line(startpoint2, endpoint2);
|
dxf.AddEntity(line2);
|
}
|
|
if (Down > 0)
|
{
|
Vector2 endpoint3 = new Vector2(realwidth - Right, realheight - Down);
|
Vector2 startpoint3 = new Vector2(Left, realheight - Down);
|
netDxf.Entities.Line line3 = new netDxf.Entities.Line(startpoint3, endpoint3);
|
dxf.AddEntity(line3);
|
}
|
if (considerSetting) dxf.SecurityDis(this); //下刀安全距离,导出OPT不需要考虑
|
|
dxf.stock = this;
|
dxf.mergeLine();
|
dxf.TShrink();
|
if (!Setting.singleDirectionCutting) dxf.Optimize(Functions.getOriginPoint(true, this));//优化刀路
|
blocks = dxf.getBlocks(3);
|
|
sortBlocks(ref blocks);
|
if (this.stockNumber == 3)
|
{
|
int a = 0;
|
}
|
}
|
private void orderHlines(ref List<List<EntityObject>> hlines)//Y由小到大排序
|
{
|
List<List<EntityObject>> sortedlines = new List<List<EntityObject>>();
|
while (hlines.Count > 0)
|
{
|
double maxy = 100 * hlines[0][0].StartPoint.Y + hlines[0][0].StartPoint.X;
|
int maxindex = 0;
|
for (int i = 1; i < hlines.Count; i++)
|
if (100 * hlines[i][0].StartPoint.Y + hlines[i][0].StartPoint.X > maxy)
|
{
|
maxy = 100 * hlines[i][0].StartPoint.Y + hlines[i][0].StartPoint.X;
|
maxindex = i;
|
}
|
sortedlines.Add(hlines[maxindex]);
|
hlines.RemoveAt(maxindex);
|
}
|
hlines = sortedlines;
|
}
|
private void CheckDircetionVlines(ref List<List<EntityObject>> vlines)//X由小到大排序
|
{
|
List<List<EntityObject>> newlines = new List<List<EntityObject>>();
|
if (Setting.singleDirectionCutting)
|
{
|
for (int i = 0; i < vlines.Count; i++)
|
{
|
if (vlines[i][0].StartPoint.Y < vlines[i][0].EndPoint.Y)
|
{
|
netDxf.Vector3 temp = new Vector3();
|
temp = vlines[i][0].StartPoint;
|
vlines[i][0].StartPoint = vlines[i][0].EndPoint;
|
vlines[i][0].EndPoint = temp;
|
}
|
}
|
}
|
}
|
private void orderVlines(ref List<List<EntityObject>> vlines)//X由小到大排序
|
{
|
List<List<EntityObject>> sortedlines = new List<List<EntityObject>>();
|
while (vlines.Count > 0)
|
{
|
double minx = 100 * vlines[0][0].StartPoint.X - vlines[0][0].StartPoint.Y;
|
int minindex = 0;
|
for (int i = 1; i < vlines.Count; i++)
|
if (100 * vlines[i][0].StartPoint.X - vlines[i][0].StartPoint.Y < minx)
|
{
|
minx = 100 * vlines[i][0].StartPoint.X - vlines[i][0].StartPoint.Y;
|
minindex = i;
|
}
|
sortedlines.Add(vlines[minindex]);
|
vlines.RemoveAt(minindex);
|
}
|
vlines = sortedlines;
|
}
|
private void orderArcs(ref List<List<EntityObject>> arcs)//X由小到大排序
|
{
|
List<List<EntityObject>> sortedarcs = new List<List<EntityObject>>();
|
while (arcs.Count > 0)
|
{
|
double minx = 100 * arcs[0][0].StartPoint.X - arcs[0][0].StartPoint.Y;
|
int minindex = 0;
|
for (int i = 1; i < arcs.Count; i++)
|
if (100 * arcs[i][0].StartPoint.X - arcs[i][0].StartPoint.Y < minx)
|
{
|
minx = 100 * arcs[i][0].StartPoint.X - arcs[i][0].StartPoint.Y;
|
minindex = i;
|
}
|
sortedarcs.Add(arcs[minindex]);
|
arcs.RemoveAt(minindex);
|
}
|
arcs = sortedarcs;
|
}
|
public void sortBlocks(ref List<List<EntityObject>> blocks)
|
{
|
List<List<EntityObject>> sorted = new List<List<EntityObject>>();
|
List<List<EntityObject>> Hlines = new List<List<EntityObject>>();
|
List<List<EntityObject>> Vlines = new List<List<EntityObject>>();
|
List<List<EntityObject>> Xlines = new List<List<EntityObject>>();
|
List<List<EntityObject>> Arcs = new List<List<EntityObject>>();
|
List<List<EntityObject>> circles = new List<List<EntityObject>>();
|
List<List<EntityObject>> composedObjects = new List<List<EntityObject>>();
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
if (blocks[i].Count > 1)
|
composedObjects.Add(blocks[i]);
|
else
|
switch (blocks[i][0].Type)
|
{
|
case EntityType.Line:
|
|
Line line = (Line)blocks[i][0];
|
line.length = Functions.getVector3Length(line.StartPoint, line.EndPoint);
|
if (line.length > 4)
|
{
|
if (line.StartPoint.X == line.EndPoint.X)
|
Vlines.Add(blocks[i]);
|
else if (line.StartPoint.Y == line.EndPoint.Y)
|
Hlines.Add(blocks[i]);
|
else Xlines.Add(blocks[i]);
|
}
|
break;
|
case EntityType.Arc:
|
Arc arc = (Arc)blocks[i][0];
|
Arcs.Add(blocks[i]);
|
break;
|
case EntityType.Circle:
|
Circle cir = (Circle)blocks[i][0];
|
if (cir.Radius > Setting.hole)//剔除孔洞
|
circles.Add(blocks[i]);
|
break;
|
default:
|
composedObjects.Add(blocks[i]);
|
break;
|
}
|
}
|
orderHlines(ref Hlines);
|
orderVlines(ref Vlines);
|
// stockFun.connectVline(ref Vlines);
|
//stockFun.connectHline(ref Hlines);
|
CheckDircetionVlines(ref Vlines);
|
orderVlines(ref Xlines);
|
orderArcs(ref Arcs);
|
sorted.AddRange(Hlines);
|
sorted.AddRange(Vlines);
|
sorted.AddRange(Xlines);
|
sorted.AddRange(Arcs);
|
sorted.AddRange(circles);
|
sorted.AddRange(composedObjects);
|
blocks = sorted;
|
}
|
|
public void breakBlock(int index)
|
{
|
if (blocks == null) return;
|
if (index > blocks.Count - 1) return;
|
if (blocks[index].Count == 1) return;
|
List<EntityObject> copy = blocks[index];
|
blocks.RemoveAt(index);
|
for (int i = 0; i < copy.Count; i++)
|
{
|
List<EntityObject> singleblock = new List<EntityObject>();
|
singleblock.Add(copy[i]);
|
blocks.Insert(index + i, singleblock);
|
}
|
}
|
public void deleteBlock(int index)
|
{
|
if (blocks == null) return;
|
if (index > blocks.Count - 1) return;
|
blocks.RemoveAt(index);
|
}
|
public void deleteBlock(int index, int j)
|
{
|
if (blocks == null) return;
|
if (index > blocks.Count - 1) return;
|
if (j > blocks[index].Count - 1) return;
|
if (j == 0 || j == blocks[index].Count - 1)
|
blocks[index].RemoveAt(j);
|
}
|
|
public void reverseBlock(int index)
|
{
|
if (blocks == null) return;
|
if (index > blocks.Count - 1) return;
|
for (int j = 0; j < blocks[index].Count; j++)
|
reverseBlock(index, j);
|
blocks[index].Reverse();
|
}
|
public void reverseBlock(int index, int j)
|
{
|
if (blocks == null) return;
|
if (index > blocks.Count - 1) return;
|
if (j < 0 || j > blocks[index].Count - 1) return;
|
switch (blocks[index][j].Type)
|
{
|
case EntityType.Line:
|
|
Vector3 temp = blocks[index][j].StartPoint;
|
blocks[index][j].StartPoint = blocks[index][j].EndPoint;
|
blocks[index][j].EndPoint = temp;
|
break;
|
case EntityType.Arc:
|
Arc arc = (Arc)blocks[index][j];
|
//double t = ((Arc)blocks[index][j]).StartAngle;
|
//((Arc)blocks[index][j]).StartAngle = ((Arc)blocks[index][j]).EndAngle;
|
//((Arc)blocks[index][j]).EndAngle = t;
|
((Arc)blocks[index][j]).clockwise = !((Arc)blocks[index][j]).clockwise;
|
break;
|
}
|
|
}
|
public bool hasarc()
|
{
|
bool hasarc = false;
|
foreach (Polygon poly in this.polys)
|
{
|
if (poly.temp_number == 0)
|
{
|
hasarc = true;
|
break;
|
}
|
else
|
{
|
DxfDocument polydoc = new netDxf.DxfDocument();
|
poly.addArcToDXF(this, ref polydoc, true);
|
if (polydoc.Lines.Count < polydoc.addedEntity.Count)
|
{
|
hasarc = true;
|
break;
|
}
|
}
|
}
|
return hasarc;
|
}
|
public DxfDocument getHVlinesDoc(bool ForCut, bool considerSetting = true)
|
{
|
if (!canbeshowed) return null;
|
SetCutlines(true, true);
|
List<CutLine> lines = cutlines;
|
DxfDocument dxf = new DxfDocument();
|
dxf.ForCut = ForCut;
|
dxf.stock = this;
|
//把线写入图层中
|
foreach (CutLine line in lines)
|
{
|
if (line == null) continue;
|
Vector2 startpoint = new Vector2(line.start.X, line.start.Y);
|
Vector2 endpoint = new Vector2(line.end.X, line.end.Y);
|
if (//startpoint.Y ==endpoint .Y&&startpoint .Y >Setting.CutError2&&
|
Functions.getVector3Length(new Vector3(startpoint.X, startpoint.Y, 1), new Vector3(endpoint.X, endpoint.Y, 1)) > 0.5)
|
{
|
netDxf.Entities.Line DxfLine = new netDxf.Entities.Line(startpoint, endpoint);
|
dxf.AddEntity(DxfLine);
|
}
|
}
|
dxf.RemoveLimit(); //过滤超限的dxf,必须在切割线move(left,down)之前使用
|
//如果有修边量:1.所有EntityObject要move(left,top)。2.添加四条修边直线
|
if (Math.Max(Left, Right) > 0 || Math.Max(Up, Down) > 0)
|
{
|
dxf.Move(Left, Up); //预处理切边距
|
if (Up > 0)
|
{
|
Vector2 startpoint1 = new Vector2(0, Up);
|
Vector2 endpoint1 = new Vector2(realwidth, Up);
|
netDxf.Entities.Line line1 = new netDxf.Entities.Line(startpoint1, endpoint1);
|
dxf.AddEntity(line1);
|
}
|
if (Right > 0)
|
{
|
Vector2 startpoint2 = new Vector2(realwidth - Right, 0);
|
Vector2 endpoint2 = new Vector2(realwidth - Right, realheight);
|
netDxf.Entities.Line line2 = new netDxf.Entities.Line(startpoint2, endpoint2);
|
dxf.AddEntity(line2);
|
}
|
if (Down > 0)
|
{
|
Vector2 startpoint3 = new Vector2(realwidth, realheight - Down);
|
Vector2 endpoint3 = new Vector2(0, realheight - Down);
|
netDxf.Entities.Line line3 = new netDxf.Entities.Line(startpoint3, endpoint3);
|
dxf.AddEntity(line3);
|
}
|
if (Left > 0)
|
{
|
Vector2 startpoint4 = new Vector2(Left, realheight);
|
Vector2 endpoint4 = new Vector2(Left, 0);
|
netDxf.Entities.Line line4 = new netDxf.Entities.Line(startpoint4, endpoint4);
|
dxf.AddEntity(line4);
|
}
|
}
|
dxf.mergeLine();//去重
|
return dxf;
|
}
|
public DxfDocument getHVlinesDoc_Lisec(bool ForCut, bool considerSetting = true)
|
{
|
if (!canbeshowed) return null;
|
|
//if (blocks == null)
|
// setBlocks();
|
//DxfDocument dxf = new DxfDocument();
|
//dxf.ForCut = ForCut;
|
//dxf.stock = this;
|
////把线写入图层中
|
//for (int i = 0; i < blocks.Count; i++)
|
//{
|
// for (int j = 0; j < blocks[i].Count; j++)
|
// {
|
// Vector2 startpoint = new Vector2(blocks[i][j].StartPoint.X, blocks[i][j].StartPoint.Y);
|
// Vector2 endpoint = new Vector2(blocks[i][j].EndPoint.X, blocks[i][j].EndPoint.Y);
|
// if (Functions.getVector3Length(new Vector3(startpoint.X, startpoint.Y, 1), new Vector3(endpoint.X, endpoint.Y, 1)) > 0.5)
|
// {
|
// netDxf.Entities.Line DxfLine = new netDxf.Entities.Line(startpoint, endpoint);
|
// dxf.AddEntity(DxfLine);
|
// }
|
// }
|
//}
|
|
SetCutlines(true, true);
|
List<CutLine> lines = cutlines;
|
DxfDocument dxf = new DxfDocument();
|
dxf.ForCut = ForCut;
|
dxf.stock = this;
|
//把线写入图层中
|
foreach (CutLine line in lines)
|
{
|
if (line == null) continue;
|
Vector2 startpoint = new Vector2(line.start.X, line.start.Y);
|
Vector2 endpoint = new Vector2(line.end.X, line.end.Y);
|
if (Functions.getVector3Length(new Vector3(startpoint.X, startpoint.Y, 1), new Vector3(endpoint.X, endpoint.Y, 1)) > 0.5)
|
{
|
netDxf.Entities.Line DxfLine = new netDxf.Entities.Line(startpoint, endpoint);
|
dxf.AddEntity(DxfLine);
|
}
|
}
|
dxf.RemoveLimit();
|
dxf.mergeLine();//去重
|
return dxf;
|
}
|
public DxfDocument getPolylinesDocWidthoutArc(bool ForCut)
|
{
|
if (!canbeshowed) return null;
|
SetCutlines(true, false);
|
List<CutLine> lines = cutlines;
|
DxfDocument dxf = new DxfDocument();
|
dxf.ForCut = ForCut;
|
dxf.stock = this;
|
foreach (CutLine line in lines)
|
{
|
if (line == null) continue;
|
|
Vector2 startpoint = new Vector2(line.start.X, line.start.Y);
|
Vector2 endpoint = new Vector2(line.end.X, line.end.Y);
|
if (Functions.getVector3Length(new Vector3(startpoint.X, startpoint.Y, 1), new Vector3(endpoint.X, endpoint.Y, 1)) > 2)
|
{
|
netDxf.Entities.Line DxfLine = new netDxf.Entities.Line(startpoint, endpoint);
|
dxf.AddEntity(DxfLine);
|
}
|
}
|
List<Polygon> ps = expandPolys();//写入来自DXF成品的切割线
|
foreach (Polygon p in ps)
|
{
|
p.addArcToDXF(this, ref dxf);
|
}
|
dxf.Move(Left, Up);
|
return dxf;
|
}
|
public List<EntityObject> ToCutObjects(bool forCut)
|
{
|
List<EntityObject> results = new List<EntityObject>();
|
netDxf.DxfDocument hvdoc = getHVlinesDoc(forCut);
|
if (hvdoc == null) return results;
|
foreach (netDxf.Entities.Line l in hvdoc.Lines)//网格线
|
{
|
if (Functions.getVector3Length(l.StartPoint, l.EndPoint) >= 2)
|
results.Add(l.Clone() as Line);
|
}
|
if (!hasarc())
|
{
|
netDxf.DxfDocument doc = getPolylinesDocWidthoutArc(forCut);//内部线
|
if (doc == null) return results;
|
foreach (netDxf.Entities.Line l in doc.Lines)
|
{
|
if (Functions.getVector3Length(l.StartPoint, l.EndPoint) >= 2)
|
results.Add(l);
|
}
|
return results;
|
}
|
foreach (Polygon poly in this.polys) //有弧线时,按小片顺序切内部信息
|
{
|
netDxf.DxfDocument doc = null;
|
poly.move(Left, Up);
|
if (poly.temp_number == 0)//DXF
|
{
|
doc = poly.dxfpoly.Str2dxfDocument();
|
doc.Move(Left, Up);
|
doc.stock = this;
|
|
}
|
else//模板
|
{
|
doc = new netDxf.DxfDocument();
|
doc.stock = this;
|
poly.addArcToDXF(this, ref doc, forCut);
|
if (doc != null)
|
foreach (netDxf.Entities.Line l in doc.Lines)
|
{
|
if (directPacking.Setting.singleDirectionCutting)//正向切割对斜线也起作用
|
{
|
if (l.StartPoint.X > l.EndPoint.X)
|
{
|
netDxf.Vector3 temp = new Vector3();
|
temp = l.StartPoint;
|
l.StartPoint = l.EndPoint;
|
l.EndPoint = temp;
|
}
|
}
|
}
|
}
|
if (doc != null)
|
{
|
foreach (EntityObject o in doc.addedEntity.Values)
|
{
|
if (o.Type == EntityType.Line && Functions.isExternalRectangleLine((Line)o, poly))//线段属于外包矩形就不添加,否则会重线
|
continue;
|
else if (o.Type == EntityType.Ellipse)
|
results.AddRange(((Ellipse)o).ToArcs());
|
else
|
results.Add(o);
|
}
|
}
|
poly.move(-Left, -Up);
|
}
|
return results;
|
}
|
public Bitmap getbitmapFromObjects(float width, float height, List<int> indexs, 设备驱动 form)
|
{
|
float ratio = Math.Min(width / (Width + Right + Left), (height) / (Height + Up + Down));
|
Bitmap realmap = new Bitmap((int)(realwidth * ratio) + 2, (int)(realheight * ratio) + 40 + 2);
|
Graphics g = Graphics.FromImage(realmap);
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
|
SolidBrush brush = new SolidBrush(Color.White);
|
g.FillRectangle(brush, 0, 0, realwidth * ratio, realheight * ratio);
|
if (!canbeshowed)
|
{
|
string s = Sentences.mianfeibanbenjinkechakan;
|
Font f = new Font("宋体", marryFontSizeString(1, s, realmap.Width / 2, realmap.Height), FontStyle.Bold | FontStyle.Underline);
|
SizeF size = g.MeasureString(s, f);
|
g.DrawString(s, f, new SolidBrush(Color.Indigo), new PointF((realmap.Width - size.Width) / 2, (realmap.Height - size.Height) / 2));
|
g.DrawRectangle(new Pen(Color.Black, 2), 0, 0, realwidth * ratio, realheight * ratio);
|
return realmap;
|
|
}
|
|
List<EntityObject> holes = new List<EntityObject>();
|
if (blocks == null)
|
setBlocks();
|
int number = 0;
|
Pen pen = new Pen(Color.Green, 1.5f);
|
System.Drawing.Drawing2D.AdjustableArrowCap lineArrow =
|
new System.Drawing.Drawing2D.AdjustableArrowCap(Functions.arrorwidth, Functions.arrorwidth, true);
|
if (Setting.displayarrow)
|
pen.CustomEndCap = lineArrow;
|
else
|
pen.CustomEndCap = new System.Drawing.Drawing2D.AdjustableArrowCap(0, 0, true);
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
blocks[i][j].Draw(g, pen, ratio, ++number);
|
}
|
}
|
List<EntityObject> allobjects = new List<EntityObject>();
|
for (int i = 0; i < blocks.Count; i++)
|
allobjects.AddRange(blocks[i]);
|
foreach (int index in indexs)
|
{
|
Pen pen2 = new Pen(new SolidBrush(Color.OrangeRed), 3);
|
pen2.CustomEndCap = lineArrow;
|
allobjects[index - 1].Draw(g, pen2, ratio, -1);//高亮当前index刀序
|
if (allobjects[index - 1].Type == EntityType.Arc && ((Arc)allobjects[index - 1]).clockwise == false)
|
{
|
form.startx.Text = Math.Round(allobjects[index - 1].EndPoint.X, 3).ToString();
|
form.starty.Text = Math.Round(realheight - allobjects[index - 1].EndPoint.Y, 3).ToString();
|
form.endx.Text = Math.Round(allobjects[index - 1].StartPoint.X, 3).ToString();
|
form.endy.Text = Math.Round(realheight - allobjects[index - 1].StartPoint.Y, 3).ToString();
|
}
|
else
|
{
|
form.startx.Text = Math.Round(allobjects[index - 1].StartPoint.X, 3).ToString();
|
form.starty.Text = Math.Round(realheight - allobjects[index - 1].StartPoint.Y, 3).ToString();
|
form.endx.Text = Math.Round(allobjects[index - 1].EndPoint.X, 3).ToString();
|
form.endy.Text = Math.Round(realheight - allobjects[index - 1].EndPoint.Y, 3).ToString();
|
}
|
if (allobjects[index - 1].Type == EntityType.Arc)
|
{
|
form.middleX.Enabled = true;
|
form.middleY.Enabled = true;
|
Vector2 point = ((Arc)allobjects[index - 1]).getMiddlePoint();
|
form.middleX.Text = point.X.ToString();
|
form.middleY.Text = (realheight - point.Y).ToString();
|
}
|
else
|
{
|
form.middleX.Enabled = false;
|
form.middleY.Enabled = false;
|
}
|
}
|
g.DrawRectangle(new Pen(Color.Black, 2), 0, 0, realwidth * ratio, realheight * ratio);
|
return realmap;
|
}
|
public Bitmap getbitmapFromObjects(float width, float height, List<int> indexs)
|
{
|
float ratio = Math.Min(width / (Width + Right + Left), (height) / (Height + Up + Down));
|
Bitmap realmap = new Bitmap((int)(realwidth * ratio) + 2, (int)(realheight * ratio) + 40 + 2);
|
Graphics g = Graphics.FromImage(realmap);
|
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.Default;
|
SolidBrush brush = new SolidBrush(Color.FromArgb(140, Color.Green));
|
g.FillRectangle(brush, 0, 0, realwidth * ratio, realheight * ratio);
|
if (!canbeshowed)
|
{
|
string s = Sentences.mianfeibanbenjinkechakan;
|
Font f = new Font("宋体", marryFontSizeString(1, s, realmap.Width / 2, realmap.Height), FontStyle.Bold | FontStyle.Underline);
|
SizeF size = g.MeasureString(s, f);
|
g.DrawString(s, f, new SolidBrush(Color.Indigo), new PointF((realmap.Width - size.Width) / 2, (realmap.Height - size.Height) / 2));
|
g.DrawRectangle(new Pen(Color.Black, 2), 0, 0, realwidth * ratio, realheight * ratio);
|
return realmap;
|
|
}
|
|
List<EntityObject> holes = new List<EntityObject>();
|
if (blocks == null)
|
setBlocks();
|
int number = 0;
|
Pen pen = new Pen(Color.White, 1.5f);
|
System.Drawing.Drawing2D.AdjustableArrowCap lineArrow =
|
new System.Drawing.Drawing2D.AdjustableArrowCap(Functions.arrorwidth, Functions.arrorwidth, true);
|
if (Setting.displayarrow)
|
pen.CustomEndCap = lineArrow;
|
else
|
pen.CustomEndCap = new System.Drawing.Drawing2D.AdjustableArrowCap(0, 0, true);
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
blocks[i][j].Draw(g, pen, ratio, ++number);
|
}
|
}
|
List<EntityObject> allobjects = new List<EntityObject>();
|
for (int i = 0; i < blocks.Count; i++)
|
allobjects.AddRange(blocks[i]);
|
foreach (int index in indexs)
|
{
|
Pen pen2 = new Pen(new SolidBrush(Color.Yellow), 3);
|
pen2.CustomEndCap = lineArrow;
|
if (index - 1 < allobjects.Count) allobjects[index - 1].Draw(g, pen2, ratio, -1);//高亮当前index刀序
|
|
}
|
g.DrawRectangle(new Pen(Color.Black, 2), 0, 0, realwidth * ratio, realheight * ratio);
|
return realmap;
|
}
|
|
private DxfDocument getDXF()
|
{
|
DxfDocument dxf = new DxfDocument();
|
if (blocks == null) setBlocks();
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
switch (blocks[i][j].Type)
|
{
|
case EntityType.Line:
|
Vector3 start = new Vector3(blocks[i][j].StartPoint.X, realheight - blocks[i][j].StartPoint.Y, 0);
|
Vector3 end = new Vector3(blocks[i][j].EndPoint.X, realheight - blocks[i][j].EndPoint.Y, 0);
|
Line line = new Line(start, end);
|
dxf.AddEntity(line);
|
break;
|
case EntityType.Arc:
|
Arc arc = (Arc)blocks[i][j];
|
Vector2 center = new Vector2(arc.Center.X, realheight - arc.Center.Y);
|
Arc mirrorarc = new Arc(center, arc.Radius, 360 - arc.EndAngle, 360 - arc.StartAngle);
|
dxf.AddEntity(mirrorarc);
|
break;
|
case EntityType.Circle:
|
Circle cir = (Circle)blocks[i][j];
|
Vector2 circenter = new Vector2(cir.Center.X, realheight - cir.Center.Y);
|
Circle mirrorcir = new Circle(circenter, cir.Radius);
|
dxf.AddEntity(mirrorcir);
|
break;
|
case EntityType.Spline:
|
Spline spline = (Spline)blocks[i][j];
|
List<SplineVertex> mirrorlist = new List<SplineVertex>();
|
for (int k = 0; k < spline.ControlPoints.Count; k++)
|
{
|
Vector2 point = new Vector2(spline.ControlPoints[k].Location.X, realheight - spline.ControlPoints[k].Location.Y);
|
mirrorlist.Add(new SplineVertex(point));
|
}
|
dxf.AddEntity(new Spline(mirrorlist));
|
break;
|
default: break;
|
}
|
}
|
}
|
return dxf;
|
|
}
|
public void 导出DXF(string filename, List<dxfPolygon> OrigiPolygon = null)
|
{
|
DxfDocument dxf = getDXF();
|
dxf.Save(filename);
|
}
|
private void writepolyinfo(Polygon poly, ref StreamWriter swWriteFile, ref int index, List<Polygon> simpleorderpolylist)//0-第一片 1-最后一片 -1-中间片
|
{
|
float bigwidth, bigheight, smallwidth, smallheight;
|
poly.setWidthHeight(true, true);
|
bigwidth = poly.width;
|
bigheight = poly.height;
|
poly.Expand(true);
|
poly.setWidthHeight(Setting.disXiubian, Setting.disMobian);
|
smallwidth = poly.width;
|
smallheight = poly.height;
|
|
string rownum;
|
if (poly.Contains.Count < 2)
|
rownum = poly.rownumber.ToString();
|
else
|
{
|
List<int> rownums = new List<int>();
|
foreach (Polygon p in poly.Contains)
|
if (!rownums.Contains(p.rownumber))
|
rownums.Add(p.rownumber);
|
if (rownums.Count == 1)
|
rownum = rownums[0] + "*" + poly.Contains.Count;
|
else
|
rownum = "";
|
}
|
poly.setMaxMin(true);
|
string info = "";
|
if (Setting.lianxuAngle == 0)//保伦旧格式
|
{
|
|
info = "N" + (index + 13).ToString() + " P400" + (index + 1).ToString() + "= " +
|
Functions.decimalconvert(smallwidth) + "_" + Functions.decimalconvert(smallheight) + "_" +//用来画的规格
|
Functions.decimalconvert(poly.min_x + this.Left) + "_" + Functions.decimalconvert(realheight - (poly.max_y + this.Up)) + "_" +//坐标
|
Functions.decimalconvert(smallwidth) + "_" + Functions.decimalconvert(smallheight) + "_" +//用来显示的规格
|
poly.customname + "_" + //客户
|
rownum + "_" + //序号
|
Functions.startbynum(poly.getJiahao()) + "_" +//架号
|
poly.orderid + "_" +//订单号
|
poly.productname + "_" +//产品
|
poly.lable + "_" +//加工信息
|
poly.floornumber + "_" +//楼层编号
|
poly.temp_number + "_" +//图号
|
0 + "_" +//条码号;
|
poly.count; ;
|
}
|
else
|
{
|
info = "N" + (index + 13).ToString() + " P400" + (index + 1).ToString() + "= " +
|
Functions.decimalconvert(poly.min_x + this.Left) + "_" +
|
Functions.decimalconvert(realheight - (poly.max_y + this.Up)) + "_" +//坐标
|
Functions.decimalconvert(smallwidth) + "_" + Functions.decimalconvert(smallheight) + "_" +
|
Functions.decimalconvert(smallwidth) + "_" + Functions.decimalconvert(smallheight) + "_" +//用来显示的规格
|
poly.customname + "_" + //客户
|
rownum + "_" + //序号
|
Functions.startbynum(poly.getJiahao()) + "_" +//架号
|
poly.orderid + "_" +//订单号
|
poly.productname + "_" +//产品
|
poly.lable + "_" +//加工信息
|
poly.floornumber + "_" +//楼层编号
|
poly.temp_number + "_" +//图号
|
0 + "_" +//条码号;
|
poly.count;
|
}
|
|
if (Setting.Weihong)
|
{
|
info = "N" + (index + 13).ToString() + " P400" + (index + 1).ToString() + "=" +
|
Functions.decimalconvert(bigwidth) + "_" + Functions.decimalconvert(bigheight) + "_" + //规格
|
Functions.decimalconvert(poly.min_x + this.Left) + "_" + Functions.decimalconvert(realheight - (poly.max_y + this.Up)) + "_" + //坐标
|
rownum + "_" + //序号
|
poly.customname + "_" + ///架号
|
poly.getJiahao() + "_" +
|
poly.count;//;
|
}
|
//if (Setting.Weihong)
|
//{
|
// info = "N" + (index + 13).ToString() + " P400" + (index + 1).ToString() + "= " +
|
// Functions.decimalconvert(bigwidth) + "_" + Functions.decimalconvert(bigheight) + "_" +//用来画的规格
|
// Functions.decimalconvert(poly.min_x + this.Left) + "_" + Functions.decimalconvert(realheight - (poly.max_y + this.Up)) + "_" +//坐标
|
// Functions.decimalconvert(smallwidth) + "_" + Functions.decimalconvert(smallheight) + "_" +//用来显示的规格
|
|
// 0;
|
//}
|
// simpleorderpolylist[poly.rownumber ].count;//条码号(小片数量)
|
swWriteFile.WriteLine(info);
|
index++;
|
}
|
public bool 导出Gcode(string filename, List<Polygon> simpleorderpolylist)
|
{
|
List<CutLine> lines = cutlines;
|
StreamWriter swWriteFile = new StreamWriter(filename, false, Encoding.Default);
|
swWriteFile.AutoFlush = true;
|
swWriteFile.WriteLine("N01 P3000 = " + Math.Round(realwidth, 2).ToString());
|
swWriteFile.WriteLine("N02 P3001 = " + Math.Round(realheight, 2).ToString());
|
swWriteFile.WriteLine("N03 P3002 = " + Math.Round((float)Up, 2).ToString());
|
swWriteFile.WriteLine("N04 P3003 = " + Math.Round((float)Left, 2).ToString());
|
swWriteFile.WriteLine("N05 P3004 = " + Math.Round((float)Down, 2).ToString());
|
swWriteFile.WriteLine("N06 P3005 = " + Math.Round((float)Right, 2).ToString());
|
swWriteFile.WriteLine("N07 P3006 = " + sameCount.ToString());
|
swWriteFile.WriteLine("N08 P3007 = " + glassType.ToString());
|
swWriteFile.WriteLine("N09 P3008 = " + (stockNumber + 1).ToString());
|
swWriteFile.WriteLine("N10 P3009 = " + mergedSumStocks.ToString());
|
swWriteFile.WriteLine("N12 P3011 = " + Thickness);
|
int index = 0;
|
for (int i = 0; i < polys.Count; i++)
|
writepolyinfo(polys[i], ref swWriteFile, ref index, simpleorderpolylist);
|
swWriteFile.WriteLine("G17");
|
swWriteFile.WriteLine("G92 X0 Y0");
|
swWriteFile.WriteLine("G90");
|
|
if (blocks == null)
|
setBlocks();
|
List<string> gcodes = new List<string>();
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
if (blocks[i].Count == 1)//只有一个
|
{
|
gcodes.AddRange(blocks[i][0].ConvertToGcode(realheight, true, true));
|
}
|
else
|
{
|
//for (int j = 0; j < blocks[i].Count; j++)
|
// gcodes.AddRange(blocks[i][j].ConvertToGcode(true, true));
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
if (j == 0)
|
gcodes.AddRange(blocks[i][j].ConvertToGcode(realheight, true, false));
|
else if (j == blocks[i].Count - 1)//最后一个
|
gcodes.AddRange(blocks[i][j].ConvertToGcode(realheight, false, true));
|
else
|
gcodes.AddRange(blocks[i][j].ConvertToGcode(realheight, false, false));
|
|
}
|
}
|
}
|
|
gcodes.Insert(1, "M03");
|
foreach (string s in gcodes)
|
{
|
swWriteFile.WriteLine(s);
|
}
|
swWriteFile.WriteLine("M04");
|
swWriteFile.WriteLine("G90");
|
swWriteFile.WriteLine("G00X0Y0Z0");
|
swWriteFile.WriteLine("M23");
|
swWriteFile.WriteLine("M24");
|
swWriteFile.WriteLine("M30");
|
swWriteFile.Flush();
|
swWriteFile.Close();
|
return true;
|
}
|
|
#endregion
|
|
|
#region -------------------------OPT,OTD格式------------------------------------------
|
bool IsRightChild = false;
|
public void addInfo(Polygon poly)
|
{
|
Common.cutorderpolys.Add(poly);//.getCopy(1));
|
Common.cutorderpolys[Common.cutorderpolys.Count - 1].originpoly = poly;
|
|
#region 同版图相同形状时使小片 Info 一致
|
|
//int findindex = Common.find(Common.infoPolys, poly, Common.startinfo);
|
//if (findindex == -1)
|
//{
|
// Common.infoPolys.Add(poly);
|
// instructs.Add(new Instruct("Info", Common.infoPolys.Count));
|
// poly.infoID = Common.infoPolys.Count;
|
//}
|
//else
|
//{
|
// instructs.Add(new Instruct("Info", findindex));
|
// poly.infoID = findindex;
|
//}
|
|
#endregion
|
|
|
#region 小片Info 当前工程内唯一
|
Common.infoPolys.Add(poly);
|
instructs.Add(new Instruct("Info", Common.infoPolys.Count));
|
poly.infoID = Common.infoPolys.Count;
|
#endregion
|
|
}
|
|
#region 分片顺序 注释
|
//public void setCutOrder_Instruct()//分片顺序
|
//{
|
// switch (maxLay)
|
// {
|
// case "X":
|
|
// if (polys.Count + remains.Count == 1)//单片
|
// {
|
// if (parent != null && IsRightChild) instructs.Add(new Instruct("X", Width));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (vlines.Count == 0)//有小片但是没有X向贯穿线则降级分解
|
// {
|
// if (parent == null || parent != null && IsRightChild)//根节点补充X
|
// instructs.Add(new Instruct("X", Width));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "Y";
|
// Lchild.Up = Up;//传递下去
|
// Rchild = null;
|
// }
|
// else//继续进行X向分解
|
// {
|
// guillotineLine = vlines[0];
|
// instructs.Add(new Instruct("X", guillotineLine.start.X - X));
|
// Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
// Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
// Lchild.maxLay = "X";
|
// Lchild.Up = Up;//传递下去
|
// Rchild.maxLay = "X";
|
// Rchild.Up = Up;
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
|
// case "Y":
|
|
// if (polys.Count + remains.Count == 1)//单片
|
// {
|
// if (parent.maxLay == "Y" && IsRightChild)
|
// instructs.Add(new Instruct("Y", Height));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (hlines.Count == 0)//有小片但是没有Y横向贯穿线则降级分解
|
// {
|
// if (parent.maxLay != "Y" || parent.maxLay == "Y" && IsRightChild)
|
// instructs.Add(new Instruct("Y", Height));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "Z";
|
// Rchild = null;
|
// }
|
// else//继续进行Y向分解
|
// {
|
// guillotineLine = hlines[hlines.Count - 1];
|
// instructs.Add(new Instruct("Y", Y + Height - guillotineLine.start.Y));
|
// Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);//上侧
|
// Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
// Lchild.maxLay = "Y";
|
// Rchild.maxLay = "Y";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "Z":
|
// if (polys.Count + remains.Count == 1)//单片或者余料
|
// {
|
// if (parent.maxLay == "Z" && IsRightChild) instructs.Add(new Instruct("Z", Width));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
// {
|
// if (parent.maxLay != "Z" || parent.maxLay == "Z" && IsRightChild)
|
// instructs.Add(new Instruct("Z", Width));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "V";
|
// Rchild = null;
|
// }
|
// else//继续进行Z向分解
|
// {
|
// guillotineLine = vlines[0];
|
// instructs.Add(new Instruct("Z", guillotineLine.start.X - X));
|
// Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
// Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
// Lchild.maxLay = "Z";
|
// Rchild.maxLay = "Z";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "V":
|
// if (polys.Count + remains.Count == 1)//单片
|
// {
|
// if (parent.maxLay == "V" && IsRightChild) instructs.Add(new Instruct("V", Height));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (hlines.Count == 0)//有小片但是没有横向贯穿线则报警
|
// {
|
// if (parent.maxLay != "V" || parent.maxLay == "V" && IsRightChild)
|
// instructs.Add(new Instruct("V", Height));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "W";
|
// Rchild = null;
|
// }
|
// else //继续W分解
|
// {
|
// guillotineLine = hlines[hlines.Count - 1];
|
// instructs.Add(new Instruct("V", Y + Height - guillotineLine.start.Y));
|
// Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
// Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
// Lchild.maxLay = "V";
|
// Rchild.maxLay = "V";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "W":
|
// if (polys.Count + remains.Count == 1)//单片或者余料
|
// {
|
// if (parent.maxLay == "W" && IsRightChild) instructs.Add(new Instruct("W", Width));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
// {
|
// if (parent.maxLay != "W" || parent.maxLay == "W" && IsRightChild)
|
// instructs.Add(new Instruct("W", Width));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "Q";
|
// Rchild = null;
|
// }
|
// else//继续进行V向分解
|
// {
|
// guillotineLine = vlines[0];
|
// instructs.Add(new Instruct("W", guillotineLine.start.X - X));
|
// Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
// Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
// Lchild.maxLay = "W";
|
// Rchild.maxLay = "W";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "Q":
|
// if (polys.Count == 1)//单片
|
// {
|
// if (parent.maxLay == "Q" && IsRightChild) instructs.Add(new Instruct("Q", Height));
|
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (hlines.Count == 0)//有小片但是没有横向贯穿线则降级到R
|
// {
|
// if (parent.maxLay != "Q" || parent.maxLay == "Q" && IsRightChild)
|
// instructs.Add(new Instruct("Q", Height));
|
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "R";
|
// Rchild = null;
|
|
// }
|
// else //继续Q分解
|
// {
|
// guillotineLine = hlines[hlines.Count - 1];
|
// instructs.Add(new Instruct("Q", Y + Height - guillotineLine.start.Y));
|
// Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
// Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
// Lchild.maxLay = "Q";
|
// Rchild.maxLay = "Q";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "R":
|
// if (polys.Count + remains.Count == 1)//单片或者余料
|
// {
|
// if (parent.maxLay == "R" && IsRightChild) instructs.Add(new Instruct("R", Width));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
// {
|
// if (parent.maxLay != "R" || parent.maxLay == "R" && IsRightChild)
|
// instructs.Add(new Instruct("R", Width));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "S";
|
// Rchild = null;
|
// }
|
// else//继续进行Z向分解
|
// {
|
// guillotineLine = vlines[0];
|
// instructs.Add(new Instruct("R", guillotineLine.start.X - X));
|
// Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
// Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
// Lchild.maxLay = "R";
|
// Rchild.maxLay = "R";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "S":
|
// if (polys.Count + remains.Count == 1)//单片
|
// {
|
// if (parent.maxLay == "S" && IsRightChild) instructs.Add(new Instruct("S", Height));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (hlines.Count == 0)//有小片但是没有横向贯穿线则报警
|
// {
|
// if (parent.maxLay != "S" || parent.maxLay == "S" && IsRightChild)
|
// instructs.Add(new Instruct("S", Height));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "T";
|
// Rchild = null;
|
// }
|
// else //继续W分解
|
// {
|
// guillotineLine = hlines[hlines.Count - 1];
|
// instructs.Add(new Instruct("S", Y + Height - guillotineLine.start.Y));
|
// Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
// Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
// Lchild.maxLay = "S";
|
// Rchild.maxLay = "S";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "T":
|
// if (polys.Count + remains.Count == 1)//单片或者余料
|
// {
|
// if (parent.maxLay == "T" && IsRightChild) instructs.Add(new Instruct("T", Width));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
// {
|
// if (parent.maxLay != "T" || parent.maxLay == "T" && IsRightChild)
|
// instructs.Add(new Instruct("T", Width));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "E";
|
// Rchild = null;
|
// }
|
// else//继续进行R向分解
|
// {
|
// guillotineLine = vlines[0];
|
// instructs.Add(new Instruct("T", guillotineLine.start.X - X));
|
// Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
// Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
// Lchild.maxLay = "T";
|
// Rchild.maxLay = "T";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "E":
|
// if (polys.Count + remains.Count == 1)//单片
|
// {
|
// if (parent.maxLay == "E" && IsRightChild) instructs.Add(new Instruct("E", Height));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (hlines.Count == 0)//有小片但是没有横向贯穿线则报警
|
// {
|
// if (parent.maxLay != "E" || parent.maxLay == "E" && IsRightChild)
|
// instructs.Add(new Instruct("E", Height));
|
// Lchild = new Stock(X, Y, Width, Height);
|
// Lchild.maxLay = "F";
|
// Rchild = null;
|
// }
|
// else //继续W分解
|
// {
|
// guillotineLine = hlines[hlines.Count - 1];
|
// instructs.Add(new Instruct("E", Y + Height - guillotineLine.start.Y));
|
// Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
// Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
// Lchild.maxLay = "E";
|
// Rchild.maxLay = "E";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// case "F":
|
// if (polys.Count + remains.Count == 1)//单片或者余料
|
// {
|
// if (parent.maxLay == "F" && IsRightChild) instructs.Add(new Instruct("F", Width));
|
// if (polys.Count == 1)
|
// {
|
// if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
// {
|
// Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
// polystock.polys.Add(polys[0]);
|
// Common.shapes.Add(polystock);
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
// }
|
// addInfo(polys[0]);
|
// }
|
// Lchild = null;
|
// Rchild = null;
|
// }
|
// else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
// {
|
// if (parent.maxLay != "F" || parent.maxLay == "F" && IsRightChild)
|
// instructs.Add(new Instruct("F", Width));
|
// if (polys.Count > 0)
|
// {
|
// Common.shapes.Add(this.getCopy());
|
// instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
|
// }
|
// }
|
// else//继续进行R向分解
|
// {
|
// guillotineLine = vlines[0];
|
// instructs.Add(new Instruct("F", guillotineLine.start.X - X));
|
// Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
// Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
// Lchild.maxLay = "F";
|
// Rchild.maxLay = "F";
|
// Rchild.IsRightChild = true;
|
// }
|
// setPolysRemains();
|
// break;
|
// }
|
//}
|
#endregion
|
|
public void setOPT_Instruct()
|
{
|
switch (maxLay)
|
{
|
case "X":
|
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
if (parent != null && IsRightChild) instructs.Add(new Instruct("X", Width));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
instructs.Add(new Instruct("Y", polys[0].height));//解决Y刀衬边玻璃添加,添加日期:2025.10.31
|
addInfo(polys[0]);
|
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有X向贯穿线则降级分解
|
{
|
if (parent == null || parent != null && IsRightChild)//根节点补充X
|
instructs.Add(new Instruct("X", Width));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "Y";
|
Lchild.Up = Up;//传递下去
|
Rchild = null;
|
}
|
else//继续进行X向分解
|
{
|
guillotineLine = vlines[0];
|
instructs.Add(new Instruct("X", guillotineLine.start.X - X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "X";
|
Lchild.Up = Up;//传递下去
|
Rchild.maxLay = "X";
|
Rchild.Up = Up;
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
|
case "Y":
|
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
if (parent.maxLay == "Y" && IsRightChild)
|
instructs.Add(new Instruct("Y", Height));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (hlines.Count == 0)//有小片但是没有Y横向贯穿线则降级分解
|
{
|
if (parent.maxLay != "Y" || parent.maxLay == "Y" && IsRightChild)
|
instructs.Add(new Instruct("Y", Height));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "Z";
|
Rchild = null;
|
}
|
else//继续进行Y向分解
|
{
|
guillotineLine = hlines[hlines.Count - 1];
|
instructs.Add(new Instruct("Y", Y + Height - guillotineLine.start.Y));
|
Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);//上侧
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Lchild.maxLay = "Y";
|
Rchild.maxLay = "Y";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "Z":
|
if (polys.Count + remains.Count == 1)//单片或者余料
|
{
|
if (parent.maxLay == "Z" && IsRightChild) instructs.Add(new Instruct("Z", Width));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
{
|
if (parent.maxLay != "Z" || parent.maxLay == "Z" && IsRightChild)
|
instructs.Add(new Instruct("Z", Width));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "W";
|
Rchild = null;
|
}
|
else//继续进行Z向分解
|
{
|
guillotineLine = vlines[0];
|
instructs.Add(new Instruct("Z", guillotineLine.start.X - X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "Z";
|
Rchild.maxLay = "Z";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "W":
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
if (parent.maxLay == "W" && IsRightChild) instructs.Add(new Instruct("W", Height));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (hlines.Count == 0)//有小片但是没有横向贯穿线则报警
|
{
|
if (parent.maxLay != "W" || parent.maxLay == "W" && IsRightChild)
|
instructs.Add(new Instruct("W", Height));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "V";
|
Rchild = null;
|
}
|
else //继续W分解
|
{
|
guillotineLine = hlines[hlines.Count - 1];
|
instructs.Add(new Instruct("W", Y + Height - guillotineLine.start.Y));
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
Lchild.maxLay = "W";
|
Rchild.maxLay = "W";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "V":
|
if (polys.Count + remains.Count == 1)//单片或者余料
|
{
|
if (parent.maxLay == "V" && IsRightChild) instructs.Add(new Instruct("V", Width));
|
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
if (Width == 400)
|
{
|
float a = polys.Count > 0 ? 0 : polys[0].width * polys[0].height;
|
}
|
addInfo(polys[0]);
|
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
{
|
if (parent.maxLay != "V" || parent.maxLay == "V" && IsRightChild)
|
instructs.Add(new Instruct("V", Width));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "A";
|
Rchild = null;
|
}
|
else//继续进行V向分解
|
{
|
guillotineLine = vlines[0];
|
instructs.Add(new Instruct("V", guillotineLine.start.X - X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "V";
|
Rchild.maxLay = "V";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "A":
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
if (parent.maxLay == "A" && IsRightChild) instructs.Add(new Instruct("A", Height));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
|
}
|
else if (hlines.Count == 0)//有小片但是没有横向贯穿线则降级到R
|
{
|
if (parent.maxLay != "A" || parent.maxLay == "A" && IsRightChild)
|
instructs.Add(new Instruct("A", Height));
|
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "B";
|
Rchild = null;
|
|
}
|
else //继续Q分解
|
{
|
guillotineLine = hlines[hlines.Count - 1];
|
instructs.Add(new Instruct("A", Y + Height - guillotineLine.start.Y));
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
Lchild.maxLay = "A";
|
Rchild.maxLay = "A";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "B":
|
if (polys.Count + remains.Count == 1)//单片或者余料
|
{
|
if (parent.maxLay == "B" && IsRightChild) instructs.Add(new Instruct("B", Width));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
{
|
if (parent.maxLay != "B" || parent.maxLay == "B" && IsRightChild)
|
instructs.Add(new Instruct("B", Width));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "C";
|
Rchild = null;
|
}
|
else//继续进行R向分解
|
{
|
guillotineLine = vlines[0];
|
instructs.Add(new Instruct("B", guillotineLine.start.X - X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "B";
|
Rchild.maxLay = "B";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "C":
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
if (parent.maxLay == "C" && IsRightChild) instructs.Add(new Instruct("C", Height));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (hlines.Count == 0)//有小片但是没有横向贯穿线则降级到R
|
{
|
if (parent.maxLay != "C" || parent.maxLay == "C" && IsRightChild)
|
instructs.Add(new Instruct("C", Height));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "D";
|
Rchild = null;
|
}
|
else //继续A分解
|
{
|
guillotineLine = hlines[hlines.Count - 1];
|
instructs.Add(new Instruct("C", Y + Height - guillotineLine.start.Y));
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
Lchild.maxLay = "C";
|
Rchild.maxLay = "C";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
case "D":
|
if (polys.Count + remains.Count == 1)//单片或者余料
|
{
|
if (parent.maxLay == "D" && IsRightChild) instructs.Add(new Instruct("D", Width));
|
if (polys.Count == 1)
|
{
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
}
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
{
|
if (parent.maxLay != "D" || parent.maxLay == "D" && IsRightChild)
|
instructs.Add(new Instruct("D", Width));
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "E";
|
Rchild = null;
|
}
|
else//继续进行D向分解
|
{
|
guillotineLine = vlines[0];
|
instructs.Add(new Instruct("D", guillotineLine.start.X - X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "D";
|
Rchild.maxLay = "D";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
|
case "E":
|
if (polys.Count == 1)//单片
|
{
|
if (parent.maxLay == "E" && IsRightChild) instructs.Add(new Instruct("E", Height));
|
if (polys[0].temp_number != 100 || polys[0].Contains.Count > 1)
|
{
|
Stock polystock = new Stock(polys[0].min_x, polys[0].min_y, polys[0].width, polys[0].height);
|
polystock.polys.Add(polys[0]);
|
Common.shapes.Add(polystock);
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
}
|
addInfo(polys[0]);
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (hlines.Count == 0)//有小片但是没有横向贯穿线则降级到R
|
{
|
if (parent.maxLay != "E" || parent.maxLay == "E" && IsRightChild)
|
instructs.Add(new Instruct("E", Height));
|
if (polys.Count > 0)
|
{
|
Common.shapes.Add(this.getCopy());
|
instructs.Add(new Instruct("Shape", Common.shapes.Count));
|
Common.cannotDescript = this.getCopy();
|
}
|
}
|
else //继续A分解
|
{
|
guillotineLine = hlines[hlines.Count - 1];
|
instructs.Add(new Instruct("E", Y + Height - guillotineLine.start.Y));
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Rchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
Lchild.maxLay = "E";
|
Rchild.maxLay = "E";
|
Rchild.IsRightChild = true;
|
}
|
setPolysRemains();
|
break;
|
}
|
}
|
|
public List<string> getPattern()
|
{
|
List<string> s = new List<string>();
|
switch (Setting.FormatIndex)
|
{
|
case 10:
|
case 4:
|
s.Add("[Pattern]");
|
break;
|
case 3:
|
s.Add("[OPT_Pattern]");
|
break;
|
}
|
// s.Add("BatchNumber=" + pack.pack_id);
|
// s.Add("MaterialCode=" + wuliaodaima);
|
s.Add("GlassID=" + wuliaodaima.Trim());
|
s.Add("GlassDescription=" + (stockNumber + 1).ToString());
|
s.Add("GlassThickness=" + Thickness);
|
s.Add("GlassCoated=0");
|
s.Add("Pieces=" + sameCount.ToString());//加工次数
|
s.Add("Width=" + realwidth.ToString());
|
s.Add("Height=" + realheight.ToString());
|
s.Add("TrimLeft=" + Left.ToString());
|
s.Add("TrimBottom=" + Down.ToString());
|
return s;
|
}
|
|
#region 单次
|
public List<string> getPatternOnePieces()
|
{
|
List<string> s = new List<string>();
|
switch (Setting.FormatIndex)
|
{
|
case 10:
|
case 4:
|
s.Add("[Pattern]");
|
break;
|
case 3:
|
s.Add("[OPT_Pattern]");
|
break;
|
}
|
// s.Add("BatchNumber=" + pack.pack_id);
|
// s.Add("MaterialCode=" + wuliaodaima);
|
s.Add("GlassID=" + wuliaodaima.Trim());
|
s.Add("GlassDescription=" + (stockNumber + 1).ToString());
|
s.Add("GlassThickness=" + Thickness);
|
s.Add("GlassCoated=0");
|
s.Add("Pieces=1");//加工次数
|
s.Add("Width=" + realwidth.ToString());
|
s.Add("Height=" + realheight.ToString());
|
s.Add("TrimLeft=" + Left.ToString());
|
s.Add("TrimBottom=" + Down.ToString());
|
return s;
|
}
|
#endregion
|
|
|
public List<string> getFrame()
|
{
|
if (this.StockID == 35)
|
{
|
this.StockID = 35;
|
}
|
List<string> s = new List<string>();
|
for (int i = 0; i < collectedinstructs.Count; i++)
|
{
|
if (collectedinstructs[i].gongneng == "Shape") continue;
|
if (collectedinstructs[i].gongneng == "Info") continue;
|
string line = collectedinstructs[i].toString();
|
if (i + 1 < collectedinstructs.Count && collectedinstructs[i + 1].gongneng == "Shape")
|
{
|
line += " " + collectedinstructs[i + 1].toString();
|
if (i + 2 < collectedinstructs.Count && collectedinstructs[i + 2].gongneng == "Info")
|
line += " " + collectedinstructs[i + 2].toString();
|
}
|
else if (i + 1 < collectedinstructs.Count && collectedinstructs[i + 1].gongneng == "Info")
|
line += " " + collectedinstructs[i + 1].toString();
|
|
s.Add(line);
|
}
|
s.Add("\r\n");
|
return s;
|
}
|
|
//TODO 获取切割刀路 4.23 解开注释
|
public List<string> getCuttings()
|
{
|
List<string> s = new List<string>();
|
s.Add("[Cuttings]");
|
setBlocks();
|
if (blocks != null)
|
{
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
if (blocks[i][j].Type == EntityType.Line)
|
{
|
netDxf.Entities.Line l = (netDxf.Entities.Line)blocks[i][j];
|
#region 分片系统要求延伸竖向贯通线,以便优先使用X分片机构
|
if (l.StartPoint.Y < l.EndPoint.Y)
|
{
|
Vector3 temp = l.StartPoint;
|
l.StartPoint = l.EndPoint;
|
l.EndPoint = temp;
|
}
|
//if (Setting.thickcontrol)//
|
//{
|
// if (l.StartPoint.X == l.EndPoint.X &&
|
// Math.Abs(Math.Abs(l.EndPoint.Y - l.StartPoint.Y) - (realheight - Up - Down - 2 * Setting.baibian2)) < 1)
|
// {
|
// l.StartPoint = new Vector3(l.StartPoint.X, realheight, 0);
|
// l.EndPoint = new Vector3(l.EndPoint.X, Up, 0);
|
// }// 竖线且
|
//}
|
#endregion
|
|
if (Functions.getVector3Length(l.StartPoint, l.EndPoint) >= 2)
|
s.Add("x=" + l.StartPoint.X.ToString("f2") + " y=" + (realheight - l.StartPoint.Y).ToString("f2") + " X=" + l.EndPoint.X.ToString("f2") + " Y=" + (realheight - l.EndPoint.Y).ToString("f2"));
|
else
|
addString2List(blocks[i][j], ref s, 0, 0);
|
}
|
}
|
}
|
}
|
s.Add("\r\n");
|
return s;
|
}
|
|
|
private void addString2List(EntityObject o, ref List<string> s, float min_x, float min_y)
|
{
|
switch (o.Type)
|
{
|
case EntityType.Spline:
|
{
|
Spline spline = (Spline)o;
|
List<Line> lines = spline.Convert2Lines();
|
foreach (Line l in lines)
|
{
|
addString2List(l, ref s, min_x, min_y);
|
}
|
break;
|
}
|
case EntityType.Circle:
|
{
|
Circle circle = (Circle)o;
|
if (circle.Thickness != -2)
|
{
|
s.Add("x=" + (circle.Center.X - min_x + circle.Radius).ToString("f4") + " y=" + (circle.Center.Y - min_y).ToString("f4") +
|
" X=" + (circle.Center.X - min_x - circle.Radius).ToString("f4") + " Y=" + (circle.Center.Y - min_y).ToString("f4") + " L=" + circle.Radius.ToString("f4") + " C=1");
|
s.Add("x=" + (circle.Center.X - min_x - circle.Radius).ToString("f4") + " y=" + (circle.Center.Y - min_y).ToString("f4") +
|
" X=" + (circle.Center.X - min_x + circle.Radius).ToString("f4") + " Y=" + (circle.Center.Y - min_y).ToString("f4") + " L=" + circle.Radius.ToString("f4") + " C=1");
|
}
|
break;
|
}
|
case EntityType.Arc:
|
{
|
Arc arc = (Arc)o;
|
arc.setStartEnd();
|
string LR = "L";
|
if (arc.clockwise)
|
{
|
arc.TurnArround();
|
LR = "R";
|
}
|
s.Add("x=" + (arc.StartPoint.X - min_x).ToString("f4") + " y=" + (arc.StartPoint.Y - min_y).ToString("f4") +
|
" X=" + (arc.EndPoint.X - min_x).ToString("f4") + " Y=" + (arc.EndPoint.Y - min_y).ToString("f4") + " " + LR + "=" + arc.Radius.ToString("f4") + " C=1");
|
|
break;
|
}
|
case EntityType.Line:
|
{
|
Line l = (Line)o;
|
s.Add("x=" + (l.StartPoint.X - min_x).ToString("f4") + " y=" + (l.StartPoint.Y - min_y).ToString("f4") +
|
" X=" + (l.EndPoint.X - min_x).ToString("f4") + " Y=" + (l.EndPoint.Y - min_y).ToString("f4") + " C=1");
|
break;
|
}
|
case EntityType.Ellipse:
|
{
|
Ellipse e = (Ellipse)o;
|
List<string> ss = e.To4Arcs();
|
string[] itrms;
|
for (int j = ss.Count - 1; j >= 0; j--)
|
{
|
itrms = ss[j].Split(',');
|
s.Add("x=" + Convert.ToDouble(itrms[2]).ToString("f4") + " y=" + Convert.ToDouble(itrms[3]).ToString("f4") +
|
" X=" + Convert.ToDouble(itrms[0]).ToString("f4") + " Y=" + Convert.ToDouble(itrms[1]).ToString("f4") + " L=" + Convert.ToDouble(itrms[4]).ToString("f4") + " C=1");
|
}
|
break;
|
}
|
}
|
}
|
public List<string> getShape(int startindex)
|
{
|
List<string> s = new List<string>();
|
for (int i = startindex; i < Common.shapes.Count; i++)
|
{
|
s.Add("[Shape]");
|
s.Add("Id=" + (i + 1).ToString());
|
s.Add("Description=" + (i + 1).ToString());
|
Common.shapes[i].setPolysRemains();
|
|
if (Common.shapes[i].blocks == null)
|
Common.shapes[i].setBlocksForOPT();
|
|
List<EntityObject> allobjects = new List<EntityObject>();//全局刀路,绝对坐标
|
for (int j = 0; j < Common.shapes[i].blocks.Count; j++)
|
allobjects.AddRange(Common.shapes[i].blocks[j]);
|
for (int j = 0; j < allobjects.Count; j++)
|
{
|
|
//if (allobjects[j].StartPoint.X >= 0 && allobjects[j].StartPoint.X <= Common.shapes[i].polys[0].max_x &&
|
// allobjects[j].StartPoint.Y >= 0 && allobjects[j].StartPoint.Y <= Common.shapes[i].polys[0].max_y &&
|
// allobjects[j].EndPoint.X >= 0 && allobjects[j].EndPoint.X <= Common.shapes[i].polys[0].max_x &&
|
// allobjects[j].EndPoint.Y >= 0 && allobjects[j].EndPoint.Y <= Common.shapes[i].polys[0].max_y )
|
s.AddRange(getSingleObject(allobjects[j], Common.shapes[i]));
|
|
}
|
s.Add("\r\n");
|
}
|
return s;
|
}
|
public void setBlocksForOPT()
|
{
|
if (!canbeshowed) return;
|
List<EntityObject> objects = ToCutObjectsForOPT(true);
|
mergeCutObjects(ref objects);//去重
|
|
DxfDocument dxf = new DxfDocument();
|
foreach (EntityObject o in objects)
|
dxf.AddEntity(o);
|
|
dxf.stock = this;
|
dxf.mergeLine();
|
|
blocks = dxf.getBlocks(3);
|
sortBlocks(ref blocks);
|
|
}
|
public List<EntityObject> ToCutObjectsForOPT(bool forCut)
|
{
|
List<EntityObject> results = new List<EntityObject>();
|
netDxf.DxfDocument hvdoc = getHVlinesDoc(forCut);
|
if (hvdoc == null) return results;
|
|
if (!hasarc())
|
{
|
netDxf.DxfDocument doc = getPolylinesDocWidthoutArc(forCut);//内部线
|
if (doc == null) return results;
|
foreach (netDxf.Entities.Line l in doc.Lines)
|
{
|
if (Functions.getVector3Length(l.StartPoint, l.EndPoint) >= 2)
|
results.Add(l);
|
}
|
return results;
|
}
|
foreach (Polygon poly in this.polys) //有弧线时,按小片顺序切内部信息
|
{
|
netDxf.DxfDocument doc = null;
|
poly.move(Left, Up);
|
if (poly.temp_number == 0)//DXF
|
{
|
doc = poly.dxfpoly.Str2dxfDocument();
|
doc.Move(Left, Up);
|
doc.stock = this;
|
|
}
|
else//模板
|
{
|
doc = new netDxf.DxfDocument();
|
doc.stock = this;
|
poly.addArcToDXF(this, ref doc, forCut);
|
if (doc != null)
|
foreach (netDxf.Entities.Line l in doc.Lines)
|
{
|
if (directPacking.Setting.singleDirectionCutting)//正向切割对斜线也起作用
|
{
|
if (l.StartPoint.X > l.EndPoint.X)
|
{
|
netDxf.Vector3 temp = new Vector3();
|
temp = l.StartPoint;
|
l.StartPoint = l.EndPoint;
|
l.EndPoint = temp;
|
}
|
}
|
}
|
}
|
if (doc != null)
|
{
|
foreach (EntityObject o in doc.addedEntity.Values)
|
{
|
if (o.Type == EntityType.Line && Functions.isExternalRectangleLine((Line)o, poly))//线段属于外包矩形就不添加,否则会重线
|
continue;
|
else if (o.Type == EntityType.Ellipse)
|
results.AddRange(((Ellipse)o).ToArcs());
|
else
|
results.Add(o);
|
}
|
}
|
poly.move(-Left, -Up);
|
}
|
return results;
|
}
|
|
public List<string> get_otd_Info(int startindex)
|
{
|
List<string> s = new List<string>();
|
for (int i = startindex; i < Common.infoPolys.Count; i++)
|
{
|
Polygon p = Common.infoPolys[i];
|
p.setMaxMin();
|
p.setWidthHeight(Setting.disXiubian, Setting.disMobian);
|
p.infoID = i + 1;
|
s.Add("[Info]");
|
s.Add("Id=" + p.infoID.ToString());
|
int len = p.originjiahao.Length;
|
if (len > 7)
|
s.Add("Customer=" + p.originjiahao.Substring(len - 6, 6));
|
else
|
s.Add("Customer=" + p.originjiahao);
|
//s.Add("PosNo=" +p.rownumber );
|
//s.Add("SheetCode=" + p.infoID.ToString());
|
|
//s.Add("Customer=" + p.customname + "["+p.rownumber + "]");
|
|
//s.Add("Commission="+9 );
|
/*
|
if (Setting.FormatIndex == 3 || Setting.FormatIndex == 4)//如果是opt,otd
|
{
|
//s.Add("RackNo=" + p.originjiahao);
|
s.Add("SheetWidth=" + (p.width + 2 * p.left).ToString("f2"));
|
s.Add("SheetHeight=" + (p.height + 2 * p.down).ToString("f2"));
|
}
|
*/
|
s.Add("\r\n");
|
}
|
return s;
|
}
|
|
//OPTIMA 小片[Info] 位置 TODO
|
public List<string> getInfo(int startindex)
|
{
|
List<string> s = new List<string>();
|
|
|
//Dictionary<string, List<GlassDetailHeatModel>> dicHeatGlassInfo = ProjectDB.dicGlassHeat;
|
|
for (int i = startindex; i < Common.infoPolys.Count; i++)
|
{
|
Polygon p = Common.infoPolys[i];
|
p.setMaxMin();
|
p.setWidthHeight(Setting.disXiubian, Setting.disMobian);
|
p.infoID = i + 1;
|
s.Add("[Info]");
|
s.Add("Id=" + p.infoID.ToString());
|
int len = p.originjiahao.Length;
|
if (len > 7)
|
s.Add("RackNo=" + p.originjiahao.Substring(len - 6, 6));
|
else
|
s.Add("RackNo=" + p.originjiahao);
|
//s.Add("PosNo=" +p.rownumber );
|
//s.Add("SheetCode=" + p.infoID.ToString());
|
|
//s.Add("Customer=" + p.customname + "["+p.rownumber + "]");
|
|
//s.Add("Commission="+9 );
|
if (Setting.FormatIndex == 3 || Setting.FormatIndex == 4)//如果是opt,otd
|
{
|
//s.Add("RackNo=" + p.originjiahao);
|
s.Add("SheetWidth=" + (p.width + 2 * p.left).ToString("f2"));
|
s.Add("SheetHeight=" + (p.height + 2 * p.down).ToString("f2"));
|
|
#region 新增:切割激光打标模块
|
|
if (string.IsNullOrEmpty(p.dabiao) || string.IsNullOrWhiteSpace(p.dabiao))
|
{
|
s.Add("Pznote1=" + ProjectDB.GetOptimizeGlassId(p.ordername, p.originjiahao, p.realwidth.ToString(), p.realheight.ToString()));
|
continue;
|
}
|
|
if (p.dabiao.Contains("-"))
|
{
|
s.Add("Pznote=" + p.dabiao);
|
//s.Add("Pznote1=" + GetOptimizeGlassId(p.ordername, p.originjiahao, p.realwidth.ToString(), p.realheight.ToString(), dicHeatGlassInfo));
|
s.Add("Pznote1=" + ProjectDB.GetOptimizeGlassId(p.ordername, p.originjiahao, p.realwidth.ToString(), p.realheight.ToString()));
|
s.Add("Pznote2=" + (p.g).ToString("f2"));
|
s.Add("Pznote3=" + (p.h).ToString("f2"));
|
}
|
else {
|
|
MarkModel mm = JsonConvert.DeserializeObject<MarkModel>(p.dabiao);
|
if (string.IsNullOrEmpty(mm.trademark))
|
{
|
continue;
|
}
|
|
string markInfo = mm.trademark + ".orzx-" + mm.location + "-" + mm.xMargin + "-" + mm.yMargin + "-" + mm.xImage + "-" + mm.tag + "-" + mm.yImage + "-" + mm.tag2 + "-" + mm.tag3;
|
|
s.Add("Pznote=" + markInfo);
|
//s.Add("Pznote1=" + GetOptimizeGlassId(p.ordername, p.originjiahao, p.realwidth.ToString(), p.realheight.ToString(), dicHeatGlassInfo));
|
s.Add("Pznote1=" + ProjectDB.GetOptimizeGlassId(p.ordername, p.originjiahao, p.realwidth.ToString(), p.realheight.ToString()));
|
s.Add("Pznote2=" + (p.g).ToString("f2"));
|
s.Add("Pznote3=" + (p.h).ToString("f2"));
|
}
|
|
#endregion
|
}
|
s.Add("\r\n");
|
}
|
return s;
|
}
|
|
|
/// <summary>
|
/// 获取现补玻璃的Info信息,24.12.26添加
|
/// </summary>
|
/// <param name="startIndex"></param>
|
/// <returns></returns>
|
public List<string> getPatchInfo(int startindex) {
|
List<string> s = new List<string>();
|
|
|
//Dictionary<string, List<GlassDetailHeatModel>> dicHeatGlassInfo = ProjectDB.dicGlassHeat;
|
|
for (int i = startindex; i < Common.infoPolys.Count; i++)
|
{
|
Polygon p = Common.infoPolys[i];
|
p.setMaxMin();
|
p.setWidthHeight(Setting.disXiubian, Setting.disMobian);
|
p.infoID = i + 1;
|
s.Add("[Info]");
|
s.Add("Id=" + p.infoID.ToString());
|
int len = p.originjiahao.Length;
|
if (len > 7)
|
s.Add("RackNo=" + p.originjiahao.Substring(len - 6, 6));
|
else
|
s.Add("RackNo=" + p.originjiahao);
|
|
if (Setting.FormatIndex == 3 || Setting.FormatIndex == 4)//如果是opt,otd
|
{
|
//s.Add("SheetWidth=" + (p.realwidth).ToString("f2"));
|
//s.Add("SheetHeight=" + (p.realheight).ToString("f2"));
|
|
s.Add("SheetWidth=" + (p.width + 2 * p.left).ToString("f2"));
|
s.Add("SheetHeight=" + (p.height + 2 * p.down).ToString("f2"));
|
|
if (string.IsNullOrEmpty(p.dabiao) || string.IsNullOrWhiteSpace(p.dabiao))
|
{
|
s.Add("Pznote=" + p.dabiao);
|
s.Add("Pznote1=" + p.remarks);
|
s.Add("Pznote2=" + (p.g).ToString("f2"));
|
s.Add("Pznote3=" + (p.h).ToString("f2"));
|
continue;
|
}
|
|
if (p.dabiao.Contains("-"))
|
{
|
s.Add("Pznote=" + p.dabiao);
|
s.Add("Pznote1=" + p.remarks);
|
s.Add("Pznote2=" + (p.g).ToString("f2"));
|
s.Add("Pznote3=" + (p.h).ToString("f2"));
|
}
|
else
|
{
|
|
MarkNewModel new_mm = JsonConvert.DeserializeObject<MarkNewModel>(p.dabiao);
|
MarkModel mm = new MarkModel();
|
if (new_mm.markIcon == null) {
|
|
mm = JsonConvert.DeserializeObject<MarkModel>(p.dabiao);
|
}
|
else{
|
|
mm = new_mm.markIcon;
|
}
|
|
if (string.IsNullOrEmpty(mm.trademark))
|
{
|
continue;
|
}
|
|
string markInfo = mm.trademark + ".orzx-" + mm.location + "-" + mm.xMargin + "-" + mm.yMargin + "-" + mm.xImage + "-" + mm.tag + "-" + mm.yImage + "-" + mm.tag2 + "-" + mm.tag3;
|
|
s.Add("Pznote=" + markInfo);
|
s.Add("Pznote1=" + p.remarks);
|
s.Add("Pznote2=" + (p.g).ToString("f2"));
|
s.Add("Pznote3=" + (p.h).ToString("f2"));
|
}
|
}
|
s.Add("\r\n");
|
}
|
return s;
|
|
}
|
string GetGlassMarkLocation(string[] arg) {
|
|
string mark_ = "";
|
foreach (string str in arg)
|
{
|
mark_ += str + ",";
|
}
|
return mark_.TrimEnd(',');
|
|
}
|
|
|
|
|
public List<string> getSingleObject(EntityObject o, Stock stock)
|
{
|
List<string> s = new List<string>();
|
stock.realheight = stock.Height + stock.polys[0].down + stock.polys[0].top;
|
switch (o.Type)
|
{
|
case EntityType.Spline:
|
{
|
Spline spline = (Spline)o;
|
List<Line> lines = spline.Convert2Lines();
|
foreach (Line l in lines)
|
{
|
s.AddRange(getSingleObject(l, stock));
|
}
|
break;
|
}
|
case EntityType.Circle:
|
{
|
Circle circle = (Circle)o;
|
if (circle.Thickness != -2)
|
{
|
s.Add("x=" + (circle.Center.X - stock.X + circle.Radius).ToString("f2") + " y=" + (circle.Center.Y - stock.Y).ToString("f2") +
|
" X=" + (circle.Center.X - stock.X - circle.Radius).ToString("f2") + " Y=" + (circle.Center.Y - stock.Y).ToString("f2") + " R=" + circle.Radius.ToString("f2"));
|
s.Add("x=" + (circle.Center.X - stock.X - circle.Radius).ToString("f2") + " y=" + (circle.Center.Y - stock.Y).ToString("f2") +
|
" X=" + (circle.Center.X - stock.X + circle.Radius).ToString("f2") + " Y=" + (circle.Center.Y - stock.Y).ToString("f2") + " R=" + circle.Radius.ToString("f2"));
|
}
|
break;
|
}
|
case EntityType.Arc:
|
{
|
Arc arc = (Arc)o;
|
arc.setStartEnd();
|
string LR = "L";
|
if (arc.clockwise)
|
{
|
arc.TurnArround();
|
LR = "R";
|
}
|
if (Setting.FormatIndex == 3)
|
{
|
s.Add("x=" + (arc.EndPoint.X - stock.X).ToString("f2") + " y=" + (stock.realheight - arc.EndPoint.Y + stock.Y).ToString("f2") +
|
" X=" + (arc.StartPoint.X - stock.X).ToString("f2") + " Y=" + (stock.realheight - arc.StartPoint.Y + stock.Y).ToString("f2") + " " + LR + "=" + arc.Radius.ToString("f2") + " C=1");
|
}
|
else
|
{
|
s.Add("x=" + (arc.EndPoint.X - stock.X).ToString("f2") + " y=" + (stock.realheight - arc.EndPoint.Y + stock.Y).ToString("f2") +
|
" X=" + (arc.StartPoint.X - stock.X).ToString("f2") + " Y=" + (stock.realheight - arc.StartPoint.Y + stock.Y).ToString("f2") + " " + LR + "=" + arc.Radius.ToString("f2"));
|
}
|
break;
|
}
|
case EntityType.Line:
|
{
|
Line l = (Line)o;
|
|
if (Functions.getVector3Length(l.StartPoint, l.EndPoint) >= 2)
|
{
|
s.Add("x=" + (l.StartPoint.X - stock.X).ToString("f2") + " y=" + (stock.realheight - l.StartPoint.Y + stock.Y).ToString("f2") +
|
" X=" + (l.EndPoint.X - stock.X).ToString("f2") + " Y=" + (stock.realheight - l.EndPoint.Y + stock.Y).ToString("f2") + " C=1");
|
|
//s.Add("x=" + (l.StartPoint.X - stock.X).ToString("f2") + " y=" + (stock.realheight - l.StartPoint.Y + stock.Y).ToString("f2") +
|
// " X=" + (l.EndPoint.X - stock.X).ToString("f2") + " Y=" + (stock.realheight - l.EndPoint.Y + stock.Y).ToString("f2") + " C=1");
|
}
|
break;
|
}
|
case EntityType.Ellipse:
|
{
|
Ellipse e = (Ellipse)o;
|
List<string> ss = e.To4Arcs();
|
string[] itrms;
|
for (int j = ss.Count - 1; j >= 0; j--)
|
{
|
itrms = ss[j].Split(',');
|
s.Add("x=" + Convert.ToDouble(itrms[2]).ToString("f2") + " y=" + Convert.ToDouble(itrms[3]).ToString("f2") +
|
" X=" + Convert.ToDouble(itrms[0]).ToString("f2") + " Y=" + Convert.ToDouble(itrms[1]).ToString("f2") + " R=" + Convert.ToDouble(itrms[4]).ToString("f4"));
|
}
|
break;
|
}
|
}
|
return s;
|
}
|
public List<string> getOTDFile(bool isotd = false,int num = 100)
|
{
|
Common.startshape = Common.shapes.Count;
|
Common.startinfo = Common.infoPolys.Count;
|
|
setColloectInstructs();
|
|
List<string> s = new List<string>();
|
if (num == 1)
|
{
|
s.AddRange(getPatternOnePieces());
|
}
|
else {
|
s.AddRange(getPattern());
|
|
}
|
|
s.AddRange(getFrame());
|
|
if (Setting.FormatIndex == 3) {
|
s.AddRange(getCuttings());
|
}
|
|
s.AddRange(getShape(Common.startshape));
|
|
|
//results.AddRange(getcuttings(stock));
|
|
if (isotd)
|
{
|
s.AddRange(get_otd_Info(Common.startinfo));
|
}
|
else
|
{
|
if (globel.UserGroup == "补片")
|
{
|
s.AddRange(getPatchInfo(Common.startinfo));
|
|
}
|
else {
|
s.AddRange(getInfo(Common.startinfo));
|
|
}
|
}
|
return s;
|
}
|
|
|
public List<string> getOTDFile_asWhole()
|
{
|
Common.startshape = Common.shapes.Count;
|
Common.startinfo = Common.infoPolys.Count;
|
setColloectInstructs();
|
|
List<string> s = new List<string>();
|
s.AddRange(getPattern());
|
s.Add("X=" + Width.ToString());
|
s.Add("Y=" + Height.ToString() + " Shape=1");
|
s.Add("\r\n");
|
|
s.Add("[Shape]");
|
s.Add("Id=1");
|
s.Add("Description=1");
|
setBlocks();
|
if (blocks != null)
|
{
|
for (int i = 0; i < blocks.Count; i++)
|
{
|
for (int j = 0; j < blocks[i].Count; j++)
|
{
|
if (blocks[i][j].Type == EntityType.Line)
|
{
|
netDxf.Entities.Line l = (netDxf.Entities.Line)blocks[i][j];
|
|
#region 分片系统要求延伸竖向贯通线,以便优先使用X分片机构
|
if (l.StartPoint.Y < l.EndPoint.Y)
|
{
|
Vector3 temp = l.StartPoint;
|
l.StartPoint = l.EndPoint;
|
l.EndPoint = temp;
|
}
|
#endregion
|
|
if (Functions.getVector3Length(l.StartPoint, l.EndPoint) >= 2)
|
s.Add("x=" + l.StartPoint.X.ToString("f4") + " y=" + (realheight - l.StartPoint.Y).ToString("f4") + " X=" + l.EndPoint.X.ToString("f4") + " Y=" + (realheight - l.EndPoint.Y).ToString("f4"));
|
|
}
|
else
|
addString2List(blocks[i][j], ref s, 0, 0);
|
}
|
}
|
}
|
s.Add("\r\n");
|
//s.AddRange(getInfo(Common.startinfo));
|
return s;
|
}
|
public Bitmap getCutmap(float width, float height, Color stockColor)
|
{
|
|
float ratio = Math.Min(width / Width, height / Height);
|
Bitmap paper = new Bitmap((int)(Width * ratio), (int)(Height * ratio));
|
Graphics g = Graphics.FromImage(paper);
|
drawPolys(g, ratio, stockColor);
|
//画切割线
|
List<CutLine> lines = cutlines;
|
for (int i = 0; i < lines.Count; i++)
|
{
|
CutLine line = lines[i];
|
g.DrawLine(new Pen(Color.Red, 2), (float)(line.start.X * ratio), (float)(line.start.Y * ratio), (float)(line.end.X * ratio), (float)(line.end.Y * ratio));
|
|
}
|
return paper;
|
}
|
#endregion
|
|
|
|
#region -------------------------自动分片方法-------------------------------
|
|
|
public List<CutLine> hlines = new List<CutLine>();
|
public List<CutLine> vlines = new List<CutLine>();
|
private void orderHlines(ref List<CutLine> hlines)//Y由小到大排序
|
{
|
List<CutLine> sortedlines = new List<CutLine>();
|
while (hlines.Count > 0)
|
{
|
double miny = hlines[0].start.Y;
|
int minindex = 0;
|
for (int i = 1; i < hlines.Count; i++)
|
if (hlines[i].start.Y < miny)
|
{
|
miny = hlines[i].start.Y;
|
minindex = i;
|
}
|
sortedlines.Add(hlines[minindex]);
|
hlines.RemoveAt(minindex);
|
}
|
hlines = sortedlines;
|
}
|
private void orderVlines(ref List<CutLine> vlines)//X由小到大排序
|
{
|
List<CutLine> sortedlines = new List<CutLine>();
|
while (vlines.Count > 0)
|
{
|
double minx = vlines[0].start.X;
|
int minindex = 0;
|
for (int i = 1; i < vlines.Count; i++)
|
if (vlines[i].start.X < minx)
|
{
|
minx = vlines[i].start.X;
|
minindex = i;
|
}
|
sortedlines.Add(vlines[minindex]);
|
vlines.RemoveAt(minindex);
|
}
|
vlines = sortedlines;
|
}
|
|
|
public void getcutlines(FRectangle rec)
|
{
|
|
hlines.Clear();
|
vlines.Clear();
|
List<CutLine> cutlines = getCutlinesFromPolys(true, true);
|
List<CutLine> tempvlines = new List<CutLine>();
|
List<CutLine> temphlines = new List<CutLine>();
|
foreach (CutLine line in cutlines)
|
{
|
if (line.start.X == line.end.X)
|
{
|
line.length2 = Math.Abs(line.start.Y - line.end.Y);
|
tempvlines.Add(line);
|
}
|
if (line.start.Y == line.end.Y)
|
{
|
line.length2 = Math.Abs(line.start.X - line.end.X);
|
temphlines.Add(line);
|
}
|
}
|
tempvlines = Functions.mergeVlines(tempvlines);
|
temphlines = Functions.mergeHlines(temphlines);
|
foreach (CutLine line in tempvlines)
|
{
|
|
if (line.start.X == line.end.X &&
|
line.start.X > X + 1 && line.start.X < X + Width - 1 &&
|
Math.Abs(line.length2 - Height) < 5)//竖线去掉左右两侧的边界线
|
vlines.Add(line);
|
}
|
foreach (CutLine line in temphlines)
|
{
|
if (line.start.Y == line.end.Y &&
|
line.start.Y > Y + 1 && line.start.Y < Y + Height - 1 &&
|
Math.Abs(line.length2 - Width) < 5)//横向先去掉上下边界线
|
hlines.Add(line);
|
}
|
orderHlines(ref hlines);
|
orderVlines(ref vlines);
|
}
|
private List<Polygon> findPolyList(Stock rec, List<Polygon> polys)
|
{
|
double error = 0.3;
|
List<Polygon> resultlist = new List<Polygon>();
|
foreach (Polygon poly in polys)
|
{
|
poly.setMaxMin();
|
poly.setWidthHeight(false, true);//此处计算宽高不能有修边,否则组合的图形会丢失2016.9.22
|
|
if (poly.min_x >= rec.X - error && poly.min_y >= rec.Y - error &&
|
poly.min_x + poly.width <= rec.X + rec.Width + error &&
|
poly.min_y + poly.height <= rec.Y + rec.Height + error)
|
// resultlist.Add(poly.getCopy(1));
|
resultlist.Add(poly);
|
}
|
if (resultlist.Count == 1 && resultlist[0].width == 400 && resultlist[0].height == 1500)
|
return resultlist;
|
return resultlist;
|
}
|
private List<FRectangle> findRemainList(Stock rec, List<FRectangle> remains)
|
{
|
double error = 0.8;
|
List<FRectangle> resultlist = new List<FRectangle>();
|
foreach (FRectangle remain in remains)
|
{
|
|
if (remain.X >= rec.X - error && remain.Y >= rec.Y - error &&
|
remain.X + remain.Width <= rec.X + rec.Width + error &&
|
remain.Y + remain.Height <= rec.Y + rec.Height + error)
|
resultlist.Add(remain.getcopy());
|
}
|
return resultlist;
|
}
|
|
#endregion
|
|
#region -------------------------------自动分片--------------------
|
public Stock Lchild, Rchild;
|
public Stock parent;
|
public bool finished = false, start = false;
|
public CutLine guillotineLine;//提供的有效切割线
|
|
public List<CutLine> guillotines = new List<CutLine>();
|
public List<int> values = new List<int>();
|
public List<Instruct> instructs = new List<Instruct>();
|
public string maxLay = "X";
|
public bool alerm = false;
|
public List<Instruct> collectedinstructs = new List<Instruct>();
|
public void displayTree(TreeNode root)
|
{
|
root.Nodes.Clear();
|
root.Text = maxLay + " " + ((int)X).ToString() + "," + ((int)Y).ToString() + " " + ((int)Width).ToString() + " X " + ((int)Height).ToString();
|
root.Nodes.Add("根");
|
if (instructs.Count > 0)
|
{
|
root.Nodes[0].Tag = guillotineLine;
|
root.Nodes[0].ForeColor = Color.Brown;
|
// setFllowCount();
|
root.Nodes[0].Text = instructInfos();
|
if (guillotineLine != null)
|
{
|
guillotineLine.parent = this;
|
}
|
}
|
if (Lchild != null)
|
{
|
root.Nodes.Add("左");
|
Lchild.displayTree(root.Nodes[1]);
|
}
|
if (Rchild != null)
|
{
|
root.Nodes.Add("右");
|
Rchild.displayTree(root.Nodes[2]);
|
}
|
}
|
public void collectInstructs(ref List<Instruct> collects)
|
{
|
if (instructs.Count > 0)
|
{
|
setFllowCount();
|
collects.AddRange(instructs);
|
}
|
if (Lchild != null)
|
Lchild.collectInstructs(ref collects);
|
if (Rchild != null)
|
Rchild.collectInstructs(ref collects);
|
}
|
public void setColloectInstructs()
|
{
|
instructs.Clear();
|
setInstruct();
|
collectedinstructs.Clear();
|
collectInstructs(ref collectedinstructs);
|
|
}
|
public void setFllowCount()
|
{
|
if (instructs.Count > 0)
|
{
|
if (Lchild != null)//为指令赋值followedcount
|
instructs[0].followedcount = Lchild.instructsCount() + instructs.Count;
|
else
|
instructs[0].followedcount = instructs.Count;
|
}
|
if (instructs.Count > 1)
|
{
|
if (Lchild != null)//为指令赋值followedcount
|
instructs[1].followedcount = Lchild.instructsCount() + instructs.Count - 1;
|
else
|
instructs[1].followedcount = instructs.Count - 1;
|
}
|
}
|
public bool Alerm()//根据R指令个数是否等于小片数量
|
{
|
if (collectedinstructs.Count == 0) return false;
|
return (Rcount() != polys.Count);
|
|
}
|
public int Rcount()
|
{
|
int Rcount = 0;
|
for (int i = 0; i < collectedinstructs.Count; i++)
|
{
|
if (collectedinstructs[i].gongneng == "R" || collectedinstructs[i].gongneng == "Info") Rcount++;
|
}
|
return Rcount;
|
}
|
public List<int> Rids()
|
{
|
// setColloectInstructs();
|
List<int> ids = new List<int>();
|
for (int i = 0; i < collectedinstructs.Count; i++)
|
{
|
if (collectedinstructs[i].gongneng == "R" || collectedinstructs[i].gongneng == "Info")
|
ids.Add(collectedinstructs[i].infoID);
|
}
|
return ids;
|
}
|
public int instructsCount()
|
{
|
if (Lchild == null && Rchild == null)
|
{
|
return instructs.Count;
|
}
|
int leftcount = 0, rightcount = 0;
|
if (Lchild != null)
|
leftcount = Lchild.instructsCount();
|
if (Rchild != null)
|
rightcount = Rchild.instructsCount();
|
return leftcount + rightcount + instructs.Count;
|
}
|
|
public string instructInfos()
|
{
|
string str = "";
|
for (int i = 0; i < instructs.Count; i++)
|
str += " " + instructs[i].toString();
|
return str;
|
}
|
|
public bool isGrid()
|
{
|
List<CutLine> vcuts = new List<CutLine>();
|
List<CutLine> hcuts = new List<CutLine>();
|
List<CutLine> cutlines = getCutlinesFromPolys(true, true);
|
List<CutLine> tempvlines = new List<CutLine>();
|
List<CutLine> temphlines = new List<CutLine>();
|
foreach (CutLine line in cutlines)
|
{
|
if (line.start.X == line.end.X)
|
{
|
line.length2 = Math.Abs(line.start.Y - line.end.Y);
|
tempvlines.Add(line);
|
}
|
if (line.start.Y == line.end.Y)
|
{
|
line.length2 = Math.Abs(line.start.X - line.end.X);
|
temphlines.Add(line);
|
}
|
}
|
tempvlines = Functions.mergeVlines(tempvlines);
|
temphlines = Functions.mergeHlines(temphlines);
|
foreach (CutLine line in tempvlines)
|
{
|
|
if (Math.Abs(line.length2 - Height) < 5)//竖线去掉左右两侧的边界线
|
vcuts.Add(line);
|
}
|
foreach (CutLine line in temphlines)
|
{
|
if (Math.Abs(line.length2 - Width) < 5)//横向先去掉上下边界线
|
hcuts.Add(line);
|
}
|
return (temphlines.Count == hcuts.Count && tempvlines.Count == vcuts.Count &&
|
hcuts.Count > 0 && vcuts.Count > 0);
|
|
}
|
public bool isHstrip()//只有竖线且每条竖线都是贯穿线
|
{
|
List<CutLine> cutlines = getCutlinesFromPolys(true, true);
|
List<CutLine> tempvlines = new List<CutLine>();
|
List<CutLine> temphlines = new List<CutLine>();
|
foreach (CutLine line in cutlines)
|
{
|
if (line.start.X == line.end.X)
|
{
|
line.length2 = Math.Abs(line.start.Y - line.end.Y);
|
tempvlines.Add(line);
|
}
|
if (line.start.Y == line.end.Y && line.start.Y > Y && line.start.Y < Y + Height)
|
{
|
line.length2 = Math.Abs(line.start.X - line.end.X);
|
temphlines.Add(line);
|
}
|
}
|
if (temphlines.Count > 0) return false;
|
tempvlines = Functions.mergeVlines(tempvlines);
|
List<CutLine> vcuts = new List<CutLine>();
|
foreach (CutLine line in tempvlines)
|
{
|
|
if (Math.Abs(line.length2 - Height) < 5)//竖线去掉左右两侧的边界线
|
vcuts.Add(line);
|
}
|
|
return (tempvlines.Count == vcuts.Count
|
&& vcuts.Count > 0);
|
}
|
//有横向贯穿线且贯穿线分割出的都是横向条带hstrip
|
public bool isHstrips()
|
{
|
List<CutLine> vcuts = new List<CutLine>();
|
List<CutLine> hcuts = new List<CutLine>();
|
List<CutLine> cutlines = getCutlinesFromPolys(true, true);
|
List<CutLine> tempvlines = new List<CutLine>();
|
List<CutLine> temphlines = new List<CutLine>();
|
foreach (CutLine line in cutlines)
|
{
|
if (line.start.X == line.end.X)
|
{
|
line.length2 = Math.Abs(line.start.Y - line.end.Y);
|
tempvlines.Add(line);
|
}
|
if (line.start.Y == line.end.Y)
|
{
|
line.length2 = Math.Abs(line.start.X - line.end.X);
|
temphlines.Add(line);
|
}
|
}
|
tempvlines = Functions.mergeVlines(tempvlines);
|
temphlines = Functions.mergeHlines(temphlines);
|
foreach (CutLine line in tempvlines)
|
{
|
|
if (Math.Abs(line.length2 - Height) < 5)//竖线去掉左右两侧的边界线
|
vcuts.Add(line);
|
}
|
foreach (CutLine line in temphlines)
|
{
|
if (Math.Abs(line.length2 - Width) < 5)//横向先去掉上下边界线
|
hcuts.Add(line);
|
}
|
if (hlines.Count == 0) return false;//有横向贯穿线
|
bool flag = true;
|
for (int i = 0; i < hlines.Count; i++)
|
{
|
Stock stripstock = new Stock();
|
if (i == 0)
|
{
|
stripstock = new Stock(X, Y, Width, hlines[0].start.Y - Y);
|
stripstock.polys = findPolyList(stripstock, polys);
|
}
|
else
|
{
|
stripstock = new Stock(X, hlines[i - 1].start.Y, Width, hlines[i].start.Y - hlines[i - 1].start.Y);
|
stripstock.polys = findPolyList(stripstock, polys);
|
}
|
if (!stripstock.isHstrip()) flag = false;//每个条带都是Hstrip
|
}
|
Stock laststripstock = new Stock(X, hlines[hlines.Count - 1].start.Y, Width, Y + Height - hlines[hlines.Count - 1].start.Y);
|
laststripstock.polys = findPolyList(laststripstock, polys);
|
if (!laststripstock.isHstrip()) flag = false;
|
return flag;
|
}
|
public bool tophasRemaind()
|
{
|
if (hlines.Count == 0) return false;
|
List<FRectangle> topremainds = findRemainList(new Stock(X, Y, Width, hlines[0].start.Y - Y), remains);
|
return topremainds.Count == 1 &&
|
topremainds[0].isSame(new FRectangle(X, Y, Width, hlines[0].start.Y - Y));//有贯穿线且贯穿线上侧全部是余料
|
}
|
public bool righthasRemaind()
|
{
|
if (vlines.Count == 0) return false;
|
List<FRectangle> rights = findRemainList(new Stock(vlines[vlines.Count - 1].start.X, Y, X + Width - vlines[vlines.Count - 1].start.X, Height), remains);
|
return rights.Count == 1 &&
|
rights[0].isSame(new FRectangle(vlines[vlines.Count - 1].start.X, Y, X + Width - vlines[vlines.Count - 1].start.X, Height));//右侧全部是余料
|
}
|
public Instruct getWareInstruct(Polygon singlepoly)//标注单片的指令,
|
{
|
|
int daojiao = 0;
|
if (singlepoly.temp_number == 50 || singlepoly.temp_number == 51 || singlepoly.temp_number == 150
|
|| singlepoly.temp_number == 151 ||
|
singlepoly.lable == "D" || singlepoly.orderid == "D")
|
daojiao = 1;
|
if (singlepoly.lable == "X" || singlepoly.orderid == "X")
|
daojiao = 2;
|
switch (singlepoly.customname)
|
{
|
case "1":
|
|
return new Instruct("R", 10000 * singlepoly.width + singlepoly.height, daojiao, singlepoly);
|
|
case "2":
|
return new Instruct("U", 10000 * singlepoly.width + singlepoly.height, daojiao, singlepoly);
|
|
case "3":
|
return new Instruct("V", 10000 * singlepoly.width + singlepoly.height, daojiao, singlepoly);
|
|
default:
|
return new Instruct("T", 10000 * singlepoly.width + singlepoly.height, daojiao, singlepoly);
|
|
}
|
}
|
public bool isRemaind(FRectangle rect)
|
{
|
bool empty = true;
|
foreach (Polygon p in polys)
|
{
|
p.setMaxMin();
|
if (isPointInRect(new point(p.min_x + 1, p.min_y + 1), rect) ||
|
isPointInRect(new point(p.min_x + 1, p.max_y - 1), rect) ||
|
isPointInRect(new point(p.max_x - 1, p.min_y + 1), rect) ||
|
isPointInRect(new point(p.max_x - 1, p.max_y - 1), rect))
|
empty = false;
|
}
|
return empty;
|
}
|
public static bool isPointInRect(point p, FRectangle rect)
|
{
|
return ((p.X > rect.X)
|
&& (p.X < rect.X + rect.Width) &&
|
(p.Y >= rect.Y) &&
|
(p.Y <= rect.Y + rect.Height));
|
}
|
public void setFenpianInstruct()
|
{
|
switch (maxLay)
|
{
|
case "X":
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
guillotineLine = new CutLine(new point(X + Width + Left, Y), new point(X + +Left, Y + Height));
|
if (polys.Count == 1)
|
instructs.Add(getWareInstruct(polys[0]));
|
else
|
instructs.Add(new Instruct("A", Width));
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有X向贯穿线则降级分解
|
{
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "Y";
|
if (Left > 0)
|
instructs.Add(new Instruct("A", Left));
|
if (Down > 0)
|
instructs.Add(new Instruct("B", Down));
|
Lchild.Up = Up;//传递下去
|
Lchild.Right = Right;//传递下去
|
Rchild = null;
|
}
|
else if (tophasRemaind())//上方余料
|
{
|
if (Left > 0) instructs.Add(new Instruct("A", Left));
|
if (Down > 0) instructs.Add(new Instruct("B", Down));
|
guillotineLine = vlines[vlines.Count - 1];
|
|
instructs.Add(new Instruct("C", Up + hlines[0].start.Y));
|
Lchild = new Stock(X, Y, Width, Height - Up - hlines[0].start.Y);//去边料以后保留下侧
|
Lchild.maxLay = "X";
|
|
// Lchild.Up = Up;//传递下去
|
Lchild.Right = Right;//传递下去
|
Rchild = null;
|
}
|
else if (righthasRemaind() && Width - vlines[vlines.Count - 1].start.X <= 12)//右侧小余料则记忆,与后续Y指令之后的D合并;大余料通过A走掉
|
{
|
if (Left > 0) instructs.Add(new Instruct("A", Left));
|
if (Down > 0) instructs.Add(new Instruct("B", Down));
|
guillotineLine = vlines[vlines.Count - 1];
|
|
instructs.Add(new Instruct("XD", X + Width - guillotineLine.start.X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//去边料以后保留左侧
|
Lchild.maxLay = "X";
|
|
Lchild.Up = Up;//传递下去
|
Lchild.Right = Right;//传递下去
|
Rchild = null;
|
}
|
else if (isGrid())//格子布局直接降级到Z
|
{
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "Z";
|
Rchild = null;
|
if (Left > 0) instructs.Add(new Instruct("A", Left));
|
if (Down > 0) instructs.Add(new Instruct("B", Down));
|
if (Up > 0) instructs.Add(new Instruct("C", Up));
|
if (Right > 0) instructs.Add(new Instruct("FD", Right));
|
|
}
|
else if (isHstrips())//横向条带降级到Y
|
{
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "Y";
|
if (Left > 0) instructs.Add(new Instruct("A", Left));
|
if (Down > 0) instructs.Add(new Instruct("B", Down));
|
Lchild.Up = Up;//传递下去
|
Lchild.Right = Right;//传递下去
|
Rchild = null;
|
}
|
else//继续进行X向分解
|
{
|
int maxindex = maxVLineIndex();
|
guillotineLine = vlines[maxindex];
|
|
// List<FRectangle> leftremainds = findRemainList(new Stock(X, Y, guillotineLine.start.X-X, Height), remains);
|
// if (!leftremainds[0].isSame(new FRectangle(X, Y, guillotineLine.start.X - X, Height)))
|
{
|
instructs.Add(new Instruct("X", Left + guillotineLine.start.X - X));//左侧全是余料就丢弃该指令
|
}
|
|
if (Left > 0) instructs.Add(new Instruct("A", Left));
|
//if (Down > 0) instructs.Add(new Instruct("B", Down));
|
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "X";
|
Lchild.Up = Up;//传递下去
|
Lchild.Down = Down;
|
// Lchild.Right = Right;//传递下去
|
Rchild.maxLay = "X";
|
Rchild.Up = Up;
|
Rchild.Down = Down;
|
Rchild.Right = Right;
|
}
|
setPolysRemains();
|
break;
|
|
case "Y":
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
if (hlines.Count > 0 && isRemaind(new FRectangle(X, Y, Width, hlines[0].start.Y - Y)))//上方余料合并上修边
|
{
|
instructs.Add(new Instruct("C", hlines[0].start.Y - Y + Up));
|
}
|
else if (Up > 0)//上方无余料只有上修边
|
instructs.Add(new Instruct("C", Up));
|
if (Right > 0)
|
instructs.Add(new Instruct("D", Right));//根据资料22改
|
if (polys.Count == 1)
|
instructs.Add(getWareInstruct(polys[0]));
|
else
|
instructs.Add(new Instruct("C", Height));
|
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (hlines.Count == 0 || (hlines.Count != 1 && isGrid()))//有小片但是没有Y横向贯穿线则降级分解
|
{
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "Z";
|
//Lchild.Up = Up;//传递下去
|
//Lchild.Right = Right;//传递下去
|
Rchild = null;
|
bool exisitsY = false;
|
foreach (Instruct instruct in instructs) if (instruct.gongneng == "Y") exisitsY = true;
|
if (!exisitsY && Up > 0) instructs.Add(new Instruct("C", Up));
|
if (Right > 0) instructs.Add(new Instruct("FD", Right));
|
}
|
else//继续进行Y向分解
|
{
|
if (isRemaind(new FRectangle(X, Y, Width, hlines[0].start.Y - Y)))
|
{
|
if (hlines.Count == 1)//最后一片Y才产生C指令
|
{
|
// if (Up > 0) instructs.Add(new Instruct("C", Up));
|
guillotineLine = hlines[0];
|
instructs.Add(new Instruct("C", Up + guillotineLine.start.Y - Y));
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//去边料以后保留下侧
|
Lchild.maxLay = "Y";
|
// Lchild.Up = Up;//传递下去
|
// Lchild.Right = Right;//传递下去
|
Rchild = null;
|
|
if (Right > 0)
|
{
|
guillotineLine = new CutLine(new point(X + Width - Right, Y), new point(X + Width - Right, Y + Height));
|
instructs.Add(new Instruct("FD", Right));
|
|
}
|
|
|
}
|
else//否则连带余料与一个横向Y条带
|
{
|
guillotineLine = hlines[1];
|
instructs.Add(new Instruct("Y", Up + guillotineLine.start.Y - Y));//是否加上修边
|
Lchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);//上侧
|
Rchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Lchild.maxLay = "Y";
|
Lchild.Up = Up;//传递下去
|
Lchild.Right = Right;//传递下去
|
Rchild.maxLay = "Y";
|
// Rchild.Up = Up;//传递下去
|
Rchild.Right = Right;//传递下去
|
//if (Right > 0)
|
//{
|
// guillotineLine = new CutLine(new point(X + Width - Right, Y), new point(X + Width - Right, Y + Height));
|
// instructs.Add(new Instruct("D", Right));
|
|
//}
|
}
|
}
|
else
|
{
|
guillotineLine = hlines[0];
|
instructs.Add(new Instruct("Y", Up + guillotineLine.start.Y - Y));
|
if (Right > 0) instructs.Add(new Instruct("D", Right)); //根据资料22改
|
|
Lchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);//上侧
|
Rchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Lchild.maxLay = "Y";
|
Lchild.Up = Up;//传递下去
|
Lchild.Right = Right;//传递下去
|
Rchild.maxLay = "Y";
|
|
Rchild.Right = Right;//传递下去
|
|
}
|
}
|
setPolysRemains();
|
break;
|
case "Z":
|
if (tophasRemaind()) //在Z块上出现上余料
|
{
|
guillotineLine = hlines[0];
|
instructs.Add(new Instruct("E", guillotineLine.start.Y - Y));
|
Lchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//去边料以后保留下侧
|
Lchild.maxLay = "W";
|
Rchild = null;
|
}
|
|
else if (polys.Count + remains.Count == 1)//单片或者余料
|
{
|
guillotineLine = new CutLine(new point(X + Width, Y), new point(X + Width, Y + Height));
|
if (polys.Count == 1)
|
instructs.Add(getWareInstruct(polys[0]));
|
//else
|
// instructs.Add(new Instruct("E", Height));
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (vlines.Count == 0)//有小片但是没有Z竖向贯穿线则降级分解
|
{
|
Lchild = new Stock(X, Y, Width, Height);
|
Lchild.maxLay = "W";
|
Rchild = null;
|
}
|
else if (righthasRemaind())
|
{
|
guillotineLine = vlines[vlines.Count - 1];
|
instructs.Add(new Instruct("D", X + Width - guillotineLine.start.X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//去边料以后保留左侧
|
Lchild.maxLay = "Z";
|
Rchild = null;
|
}
|
|
else//继续进行Z向分解
|
{
|
guillotineLine = vlines[0];
|
instructs.Add(new Instruct("Z", guillotineLine.start.X - X));
|
Lchild = new Stock(X, Y, guillotineLine.start.X - X, Height);//左侧
|
Rchild = new Stock(guillotineLine.start.X, Y, X + Width - guillotineLine.start.X, Height);
|
Lchild.maxLay = "W";
|
Rchild.maxLay = "Z";
|
}
|
setPolysRemains();
|
break;
|
case "W":
|
if (polys.Count + remains.Count == 1)//单片
|
{
|
guillotineLine = new CutLine(new point(X, Y), new point(X, Y + Height));
|
if (polys.Count == 1)
|
instructs.Add(getWareInstruct(polys[0]));
|
else
|
instructs.Add(new Instruct("E", Height));
|
Lchild = null;
|
Rchild = null;
|
}
|
else if (hlines.Count == 0)//有小片但是没有横向贯穿线则报警
|
{
|
Lchild = null;
|
Rchild = null;
|
alerm = true;
|
}
|
else //继续W分解
|
{
|
guillotineLine = hlines[0];
|
List<FRectangle> topremainds = filterRemainList(new Stock(X, Y, Width, hlines[0].start.Y - Y), remains);
|
if (topremainds.Count == 1 &&
|
topremainds[0].isSame(new FRectangle(X, Y, Width, hlines[0].start.Y - Y)))//有贯穿线且贯穿线上侧全部是余料
|
{
|
//instructs.Add(new Instruct("E", guillotineLine.start.Y - Y));
|
}
|
else
|
{
|
instructs.Add(new Instruct("W", guillotineLine.start.Y - Y));
|
}
|
Rchild = new Stock(X, guillotineLine.start.Y, Width, Y + Height - guillotineLine.start.Y);//下侧
|
Lchild = new Stock(X, Y, Width, guillotineLine.start.Y - Y);
|
Lchild.maxLay = "W";
|
Rchild.maxLay = "W";
|
}
|
setPolysRemains();
|
break;
|
}
|
}
|
|
private List<FRectangle> filterRemainList(Stock rec, List<FRectangle> remains)
|
{
|
double error = 0.3;
|
List<FRectangle> resultlist = new List<FRectangle>();
|
foreach (FRectangle remain in remains)
|
{
|
|
if (remain.X >= rec.X - error &&
|
remain.Y >= rec.Y - error &&
|
remain.X + remain.Width <= rec.X + rec.Width + error &&
|
remain.Y + remain.Height <= rec.Y + rec.Height + error)
|
resultlist.Add(remain.getcopy());
|
}
|
return resultlist;
|
}
|
private void setInstruct()
|
{
|
//TODOTEST
|
getcutlines(new FRectangle(X, Y, Width, Height));
|
|
//if (Setting.FormatIndex == 10)
|
// setFenpianInstruct();
|
|
setOPT_Instruct();
|
|
if (Lchild != null)
|
{
|
Lchild.setInstruct();
|
}
|
if (Rchild != null)
|
{
|
Rchild.setInstruct();
|
}
|
}
|
public void setPolysRemains()
|
{
|
if (Lchild != null)
|
{
|
Lchild.polys = findPolyList(Lchild, polys);
|
Lchild.remains = findRemainList(Lchild, remains);
|
Lchild.parent = this;
|
}
|
if (Rchild != null)
|
{
|
Rchild.polys = findPolyList(Rchild, polys);
|
Rchild.remains = findRemainList(Rchild, remains);
|
Rchild.parent = this;
|
}
|
|
}
|
//以下处理寻求最大匹配条带问题(门窗旋转)
|
public bool containsRect(Polygon rectpoly)
|
{
|
foreach (Polygon poly in polys)
|
{
|
if (poly.width == rectpoly.width && poly.height == rectpoly.height) return true;
|
}
|
return false;
|
}
|
public bool containsAllPolysofStock(Stock stock)
|
{
|
foreach (Polygon poly in stock.polys)
|
{
|
if (!containsRect(poly)) return false;
|
}
|
return true;
|
}
|
public bool isEqualStock(Stock stock)
|
{
|
if (containsAllPolysofStock(stock) && stock.containsAllPolysofStock(this)) return true;
|
return false;
|
}
|
public int maxVLineIndex()
|
{
|
if (vlines.Count == 1) return 0;
|
int index = 0;
|
//根据vlines分割成不同的条带stock,在条带stock里面
|
List<Stock> splitedstocks = new List<Stock>();
|
Stock first = new Stock(X, Y, vlines[0].start.X - X, Height);//加入第一个
|
first.polys = first.findPolyList(first, polys);
|
splitedstocks.Add(first);
|
|
for (int i = 1; i < vlines.Count; i++)
|
{
|
Stock stock = new Stock(vlines[i - 1].start.X, Y, vlines[i].start.X - vlines[i - 1].start.X, Height);//加入中间的stock
|
stock.polys = stock.findPolyList(stock, polys);
|
splitedstocks.Add(stock);
|
}
|
|
Stock last = new Stock(vlines[vlines.Count - 1].start.X, Y, X + Width - vlines[vlines.Count - 1].start.X, Height);//加入最后一个
|
last.polys = last.findPolyList(last, polys);
|
splitedstocks.Add(last);
|
//寻找最大重复度
|
for (int i = 1; i < splitedstocks.Count; i++)
|
{
|
if (splitedstocks[i].isEqualStock(splitedstocks[i - 1]))
|
index = i;
|
}
|
return index;
|
}
|
#endregion
|
|
}
|
public class Instruct
|
{
|
public string gongneng;
|
public int followedcount;
|
public double XYmove;
|
public int infoID = 0;
|
public Polygon poly;
|
public Instruct(string g, double xy, int ID, Polygon poly)
|
{
|
gongneng = g;
|
infoID = ID;
|
XYmove = xy;
|
this.poly = poly;
|
}
|
public Instruct(string g, float xy, int ID)
|
{
|
gongneng = g;
|
infoID = ID;
|
XYmove = xy;
|
}
|
public Instruct(string g, float xy)
|
{
|
gongneng = g;
|
XYmove = xy;
|
}
|
public Instruct(string g, int ID)
|
{
|
gongneng = g;
|
infoID = ID;
|
}
|
public string toString()
|
{
|
if (gongneng == "Info")
|
return "Info=" + infoID;
|
if (gongneng == "Shape")
|
return "Shape=" + infoID;
|
|
switch (gongneng)
|
{
|
case "Y": gongneng = " " + gongneng; break;
|
case "Z": gongneng = " " + gongneng; break;
|
case "W": gongneng = " " + gongneng; break;
|
case "V": gongneng = " " + gongneng; break;
|
case "A": gongneng = " " + gongneng; break;
|
case "B": gongneng = " " + gongneng; break;
|
case "C": gongneng = " " + gongneng; break;
|
case "D": gongneng = " " + gongneng; break;
|
|
}
|
if (Setting.FormatIndex == 4 || Setting.FormatIndex == 3 || Setting.FormatIndex == 10)
|
return gongneng + "=" + XYmove.ToString("f2");
|
|
|
return "";
|
}
|
public Stock parent;
|
}
|
class Strip
|
{
|
public int id;
|
public double x, y, width, height, xshift, yshift;
|
public List<Polygon> polys = new List<Polygon>();
|
public Strip(int ID) { id = ID; }
|
public string toString()
|
{
|
string str = "";
|
for (int i = 0; i < polys.Count; i++)
|
{
|
str += polys[i].rownumber.ToString();
|
}
|
return str;
|
}
|
public bool contains(Strip strip)//一个条带是否包含另一个条带的所有小片
|
{
|
string str = toString();
|
foreach (Polygon p in strip.polys)
|
{
|
if (!str.Contains(p.rownumber.ToString()))
|
return false;
|
}
|
return true;
|
}
|
public void setheight()
|
{
|
float miny = 10000, maxy = 0;
|
foreach (Polygon p in polys)
|
{
|
if (p.min_y < miny) miny = p.min_y;
|
if (p.max_y > maxy) maxy = p.max_y;
|
}
|
height = maxy - miny;
|
}
|
|
}
|
}
|