You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

240 lines
8.9 KiB
C#

1 month ago
using Clipper2Lib;
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace DeepNestLib
{
public class DfdParser
{
public DfdParser() { }
public static HashSet<int> ExportPlacements(IEnumerable<NFP> polygons, IEnumerable<NFP> sheets
, double offsetX = 0, double offsetY = 0, Func<NFP, int, PointF[]> fun = null)
{
List<KeyValuePair<int, PointF[]>> lstWell = new List<KeyValuePair<int, PointF[]>>();
foreach (var item in polygons)
{
if (!sheets.Contains(item))
{
if (!item.fitted) continue;
}
var m = new Matrix();
m.Translate((float)(item.x + offsetX), (float)(item.y + offsetY));
m.Rotate(item.rotation);
PointF[] pp = null;
int nLayerType = 0;
// 写出井支
if (item.Name != null)
{
if (item.Name.Equals("双侧"))
{
pp = fun?.Invoke(item, 0);
nLayerType = 0;
}
else if (item.Name.Equals("单侧"))
{
pp = fun?.Invoke(item, 1);
nLayerType = 1;
}
}
else
{
pp = item.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray();
}
m.TransformPoints(pp);
lstWell.Add(new KeyValuePair<int, PointF[]>(nLayerType, pp));
}
// 剔除重复的井位
HashSet<int> removed = FindDuplicate(lstWell);
return removed;
}
public static HashSet<int> Export(string path, IEnumerable<NFP> polygons, IEnumerable<NFP> sheets
, double offsetX = 0, double offsetY = 0, Func<NFP, int, PointF[]> fun=null)
{
List<KeyValuePair<int, PointF[]>> lstBorder = new List<KeyValuePair<int, PointF[]>>();
List<KeyValuePair<int, PointF[]>> lstWell = new List<KeyValuePair<int, PointF[]>>();
int nFirstBorder = 0;
foreach(var item in sheets)
{
var m = new Matrix();
m.Translate((float)(item.x + offsetX), (float)(item.y + offsetY));
m.Rotate(item.rotation);
PointF[] pp = item.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray();
int nLayerType = 2;
if (nFirstBorder == 0) // 边界
{
nLayerType = 3;
}
else
{
pp = fun?.Invoke(item, 2);
}
m.TransformPoints(pp);
lstBorder.Add(new KeyValuePair<int, PointF[]>(nLayerType, pp));
nFirstBorder++;
if (item.children != null)
{
foreach (var child in item.children)
{
//if (nLayerType == 3) // 边界
//{
pp = fun?.Invoke(child, 2); // 断层
// nLayerType = 2;
//}
//else
//{
// pp = child.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray();
//}
m.TransformPoints(pp);
lstBorder.Add(new KeyValuePair<int, PointF[]>(nLayerType, pp));
}
}
}
foreach (var item in polygons)//.Union(sheets)
{
if (!sheets.Contains(item))
{
if (!item.fitted) continue;
}
var m = new Matrix();
m.Translate((float)(item.x + offsetX), (float)(item.y+ offsetY));
m.Rotate(item.rotation);
PointF[] pp = null;
int nLayerType = 0;
// 写出井支
if (item.Name != null)
{
if (item.Name.Equals("双侧"))
{
pp = fun?.Invoke(item, 0);
nLayerType = 0;
}
else if (item.Name.Equals("单侧"))
{
pp = fun?.Invoke(item, 1);
nLayerType = 1;
}
}
else
{
pp = item.Points.Select(z => new PointF((float)z.x, (float)z.y)).ToArray();
}
m.TransformPoints(pp);
lstWell.Add(new KeyValuePair<int, PointF[]>(nLayerType, pp));
}
// 剔除重复的井位
HashSet<int> removed = FindDuplicate(lstWell);
StringBuilder sb = new StringBuilder();
foreach(var item in lstBorder)
{
string strLayer = "断层";
if(item.Key == 3)
{
strLayer = "边界";
}
sb.AppendLine($"Layer M {strLayer}");
sb.AppendLine($"Pline");
foreach (var pt in item.Value)
{
sb.AppendLine($"{pt.X},{pt.Y}");
}
sb.AppendLine();
}
for (int i=0;i< lstWell.Count;i++)
{
if (removed.Contains(i))
{
continue;
}
KeyValuePair<int, PointF[]> item = lstWell[i];
string strLayer = "部署\\双侧";
if(item.Key==1)
{
strLayer = "部署\\单侧";
}
sb.AppendLine($"Layer M {strLayer}");
sb.AppendLine($"Pline");
foreach (var pt in item.Value)
{
sb.AppendLine($"{pt.X},{pt.Y}");
}
sb.AppendLine();
}
File.WriteAllText(path, sb.ToString(), Encoding.Default);
return removed;
}
public static HashSet<int> FindDuplicate(List<KeyValuePair<int, PointF[]>> sourcePolygons)
{
// 存储最终结果的列表
//List<NFP> result = new List<NFP>();
PathsD pathsSource = new PathsD();
foreach (var nfp in sourcePolygons)
{
PathD path = new PathD();
foreach (var pt in nfp.Value)
{
path.Add(new Clipper2Lib.PointD(pt.X, pt.Y));
}
pathsSource.Add(path);
}
// 标记删除的多边形
HashSet<int> removedIndices = new HashSet<int>();
for (int i = 0; i < pathsSource.Count; i++)
{
if (removedIndices.Contains(i)) continue; // 如果已经被移除,则跳过
for (int j = i + 1; j < pathsSource.Count; j++)
{
if (removedIndices.Contains(j)) continue; // 如果已经被移除,则跳过
// 检查两个多边形是否相交
PathsD intersection = Clipper.BooleanOp(ClipType.Intersection, new PathsD { pathsSource[i] }, new PathsD { pathsSource[j] }, FillRule.NonZero);
if (intersection != null && intersection.Count > 0)
{
// 移除单侧部井的多边形
if (sourcePolygons[i].Key == 1)
{
removedIndices.Add(i);
}
else if(sourcePolygons[j].Key == 1)
{
removedIndices.Add(j);
}
//double area1 = Clipper.Area(pathsSource[i]);
//double area2 = Clipper.Area(pathsSource[j]);
//// 保留面积较大的多边形
//if (Math.Abs(area1) >= Math.Abs(area2))
//{
// removedIndices.Add(j); // 移除面积较小的多边形
//}
//else
//{
// removedIndices.Add(i); // 移除面积较小的多边形
//}
}
}
//// 如果当前多边形未被移除,则加入结果
//if (!removedIndices.Contains(i))
//{
// result.Add(sourcePolygons[i]);
//}
}
return removedIndices;
}
}
}