|
|
|
|
|
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;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|