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.
1038 lines
38 KiB
Plaintext
1038 lines
38 KiB
Plaintext
|
1 month ago
|
using Clipper2Lib;
|
||
|
|
//using ClipperLib;
|
||
|
|
|
||
|
|
using DeepNestLib;
|
||
|
|
|
||
|
|
using GeoSigma.SigmaDrawerStyle;
|
||
|
|
|
||
|
|
using GeoSigmaDrawLib;
|
||
|
|
|
||
|
|
using SigmaDrawerElement;
|
||
|
|
|
||
|
|
using System;
|
||
|
|
using System.Collections.Generic;
|
||
|
|
using System.Diagnostics;
|
||
|
|
using System.Drawing;
|
||
|
|
using System.IO;
|
||
|
|
using System.Linq;
|
||
|
|
using System.Text;
|
||
|
|
using System.Text.RegularExpressions;
|
||
|
|
using System.Threading;
|
||
|
|
using System.Threading.Tasks;
|
||
|
|
using System.Windows.Forms;
|
||
|
|
|
||
|
|
using static System.Net.Mime.MediaTypeNames;
|
||
|
|
|
||
|
|
using Clipper = Clipper2Lib.Clipper;
|
||
|
|
|
||
|
|
namespace SmartWells
|
||
|
|
{
|
||
|
|
public delegate void IterateEventHandler(List<SheetPlacement> placements, double materialUtilization, long elapsedMilliseconds);
|
||
|
|
public delegate void ExportPlaceMentsEventHandler(Bitmap bmp, string info);
|
||
|
|
public class CaculateHelp : IDisposable
|
||
|
|
{
|
||
|
|
public IterateEventHandler IterateEvent { get; set; } = null;
|
||
|
|
public ExportPlaceMentsEventHandler ExportPlaceMentsEvent { get; set; } = null;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// web停止线程任务用
|
||
|
|
/// </summary>
|
||
|
|
CountdownEvent countdown = new CountdownEvent(0);
|
||
|
|
/// <summary>
|
||
|
|
/// 部署文件
|
||
|
|
/// </summary>
|
||
|
|
public string DeployFile { get; set; } = string.Empty;
|
||
|
|
/// <summary>
|
||
|
|
/// 边界图层
|
||
|
|
/// </summary>
|
||
|
|
public string BorderLayer { get; set; } = string.Empty;
|
||
|
|
/// <summary>
|
||
|
|
/// 断层图层
|
||
|
|
/// </summary>
|
||
|
|
public string FaultLayer { get; set; } = string.Empty;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// CoverageRate覆盖率
|
||
|
|
/// </summary>
|
||
|
|
public double CoverageRate { get; set; } = 0.0;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
///
|
||
|
|
/// </summary>
|
||
|
|
public int SingleWell { get; set; } = 0;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
///
|
||
|
|
/// </summary>
|
||
|
|
public int DoubleWell { get; set; } = 0;
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 是否已经停止运算
|
||
|
|
/// </summary>
|
||
|
|
public bool IsStop { get; set; } = true;
|
||
|
|
/// <summary>
|
||
|
|
/// 井参数
|
||
|
|
/// </summary>
|
||
|
|
public WellsConfig WellParameters { get; set; } = new WellsConfig();
|
||
|
|
/// <summary>
|
||
|
|
/// 计算参数
|
||
|
|
/// </summary>
|
||
|
|
public CaculateConfig CaculateParameter { get; set; } = new CaculateConfig();
|
||
|
|
/// <summary>
|
||
|
|
/// 显示进度事件
|
||
|
|
/// </summary>
|
||
|
|
public Action<float> DisplayProgressAction { get; set; }
|
||
|
|
|
||
|
|
public CaculateStatus Status { get; set; } = CaculateStatus.None;
|
||
|
|
public bool NeedStop
|
||
|
|
{
|
||
|
|
get
|
||
|
|
{
|
||
|
|
if (nest != null)
|
||
|
|
{
|
||
|
|
return nest.NeedStop;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
set
|
||
|
|
{
|
||
|
|
if (nest != null)
|
||
|
|
{
|
||
|
|
nest.NeedStop = value;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 图片导出的宽度
|
||
|
|
/// </summary>
|
||
|
|
public int ImageWidth { get; set; } = 500;
|
||
|
|
/// <summary>
|
||
|
|
/// 图片输出的高度
|
||
|
|
/// </summary>
|
||
|
|
public int ImageHeight { get; set; } = 400;
|
||
|
|
|
||
|
|
private SvgNestConfig nestConfig;
|
||
|
|
private double partSpacing = 200;
|
||
|
|
private double faultInflate = 10;
|
||
|
|
|
||
|
|
private double originX = 0;
|
||
|
|
private double originY = 0;
|
||
|
|
|
||
|
|
public NestingContext nest;
|
||
|
|
|
||
|
|
WellGroupParameter groupParaSide2;
|
||
|
|
WellGroupParameter groupParaSide1;
|
||
|
|
LocalContour wellBox2;
|
||
|
|
LocalContour wellBox1;
|
||
|
|
|
||
|
|
ManualResetEvent ma = new ManualResetEvent(false);
|
||
|
|
|
||
|
|
DrawerData drawer;
|
||
|
|
public DrawerData OpenDrawerFile()
|
||
|
|
{
|
||
|
|
if (!File.Exists(this.DeployFile))
|
||
|
|
{
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
if (drawer != null)
|
||
|
|
{
|
||
|
|
drawer.Dispose();
|
||
|
|
drawer = null;
|
||
|
|
}
|
||
|
|
|
||
|
|
drawer = new DrawerData();
|
||
|
|
//drawer.OpenWithDraw = true;
|
||
|
|
try
|
||
|
|
{
|
||
|
|
if (drawer.OpenFile(this.DeployFile) == false)
|
||
|
|
{
|
||
|
|
drawer.Dispose();
|
||
|
|
drawer = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
catch (Exception ex)
|
||
|
|
{
|
||
|
|
drawer.Dispose();
|
||
|
|
drawer = null;
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
return drawer;
|
||
|
|
}
|
||
|
|
public CaculateHelp()
|
||
|
|
{
|
||
|
|
this.nestConfig = new SvgNestConfig();
|
||
|
|
}
|
||
|
|
~CaculateHelp()
|
||
|
|
{
|
||
|
|
Dispose(false);
|
||
|
|
}
|
||
|
|
private bool disposed = false; // 跟踪是否已释放
|
||
|
|
/// <summary>
|
||
|
|
/// 受保护的虚方法,用于释放资源
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="disposing"></param>
|
||
|
|
protected virtual void Dispose(bool disposing)
|
||
|
|
{
|
||
|
|
if (!disposed)
|
||
|
|
{
|
||
|
|
if (disposing)
|
||
|
|
{
|
||
|
|
// 释放托管资源
|
||
|
|
Console.WriteLine("Releasing managed resources.");
|
||
|
|
}
|
||
|
|
|
||
|
|
// 释放未托管资源
|
||
|
|
if (drawer != null)
|
||
|
|
{
|
||
|
|
drawer.Dispose();
|
||
|
|
drawer = null;
|
||
|
|
}
|
||
|
|
if(this.ma!=null)
|
||
|
|
{
|
||
|
|
ma.Dispose();
|
||
|
|
}
|
||
|
|
disposed = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 实现 IDisposable 接口
|
||
|
|
/// </summary>
|
||
|
|
public void Dispose()
|
||
|
|
{
|
||
|
|
Dispose(true);
|
||
|
|
GC.SuppressFinalize(this); // 防止垃圾回收器再次调用析构函数
|
||
|
|
}
|
||
|
|
|
||
|
|
/// <summary>
|
||
|
|
/// 暂停
|
||
|
|
/// </summary>
|
||
|
|
public void Pause()
|
||
|
|
{
|
||
|
|
NeedStop = true;
|
||
|
|
Status = CaculateStatus.Pausing;
|
||
|
|
// 信号关闭阻,塞当前线程
|
||
|
|
ma.Reset();
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 继续
|
||
|
|
/// </summary>
|
||
|
|
public void Continue()
|
||
|
|
{
|
||
|
|
NeedStop = false;
|
||
|
|
if (this.Status!= CaculateStatus.Pausing
|
||
|
|
&& this.Status != CaculateStatus.Paused)
|
||
|
|
{
|
||
|
|
return;
|
||
|
|
}
|
||
|
|
Status = CaculateStatus.Working;
|
||
|
|
// 信号打开,不阻塞当前线程
|
||
|
|
ma.Set();
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 停止
|
||
|
|
/// </summary>
|
||
|
|
public void Stop()
|
||
|
|
{
|
||
|
|
NeedStop = true;
|
||
|
|
Status = CaculateStatus.Stopping;
|
||
|
|
this.IsStop = true;
|
||
|
|
ma.Set();
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// Web停止
|
||
|
|
/// </summary>
|
||
|
|
public void WebStop()
|
||
|
|
{
|
||
|
|
NeedStop = true;
|
||
|
|
Status = CaculateStatus.Stopping;
|
||
|
|
this.IsStop = true;
|
||
|
|
ma.Set();
|
||
|
|
ma.WaitOne(1000);
|
||
|
|
ma.Close();
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 保存部署图
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="resultFile"></param>
|
||
|
|
public bool SaveResult(string resultFile)
|
||
|
|
{
|
||
|
|
if (nest == null || nest.PlacedPartsCount == 0)
|
||
|
|
{
|
||
|
|
// MessageBox.Show("未产生正确的结果!", "保存结果", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
string strExt = Path.GetExtension(resultFile).ToUpper();
|
||
|
|
|
||
|
|
if (strExt == ".DXF")
|
||
|
|
{
|
||
|
|
DxfParser.Export(resultFile, nest.Polygons.ToArray(), nest.Sheets.ToArray(), this.originX, this.originY);
|
||
|
|
}
|
||
|
|
else if (strExt == ".SVG")
|
||
|
|
{
|
||
|
|
SvgParser.Export(resultFile, nest.Polygons.ToArray(), nest.Sheets.ToArray());
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
return drawer.SaveAs(resultFile);
|
||
|
|
}
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 执行计算
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="newWork"></param>
|
||
|
|
/// <returns></returns>
|
||
|
|
public bool Excute(bool newWork = true)
|
||
|
|
{
|
||
|
|
if (IsStop == false)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
NeedStop = false;
|
||
|
|
if (newWork)
|
||
|
|
{
|
||
|
|
if (OpenDrawerFile() == null)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
ma.Set();
|
||
|
|
//this.stlInfor.Text = string.Empty;
|
||
|
|
// 计算配置
|
||
|
|
if (CaculateParameter.SpecifyAngles == true)
|
||
|
|
{
|
||
|
|
nestConfig.SpecfiedAngles = CaculateParameter.SpeciaAngles.Select(it => (float)(it)).ToArray();
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{ // 旋转角度角度
|
||
|
|
nestConfig.SpecfiedAngles = null;
|
||
|
|
// 部件旋转数
|
||
|
|
nestConfig.rotations = CaculateParameter.Rotations;
|
||
|
|
nestConfig.AngleStart = (float)CaculateParameter.AngleStart;
|
||
|
|
nestConfig.AngleEnd = (float)CaculateParameter.AngleEnd;
|
||
|
|
}
|
||
|
|
|
||
|
|
// 部件间间距设置
|
||
|
|
nestConfig.spacing = 0;// CaculateParameter.WellsSpace;
|
||
|
|
partSpacing = CaculateParameter.WellsSpace;
|
||
|
|
|
||
|
|
//this.borderFile = this.txtBorderFile.Text;
|
||
|
|
//this.faultageFile = this.txtFaultage.Text;
|
||
|
|
// 打开文件
|
||
|
|
|
||
|
|
// 加载边界数据
|
||
|
|
RawDetail detail = loadLayersDetail(this.BorderLayer);// loadDetail(this.borderFile);
|
||
|
|
detail.Name = this.BorderLayer;
|
||
|
|
if (detail.Outers.Count == 0)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
if (detail.Outers.Count > 1)
|
||
|
|
{
|
||
|
|
detail.Outers.RemoveRange(1, detail.Outers.Count - 1);
|
||
|
|
}
|
||
|
|
// 计算相对坐标原点
|
||
|
|
var bbox = detail.BoundingBox();
|
||
|
|
originX = bbox.X;
|
||
|
|
originY = bbox.Y;
|
||
|
|
|
||
|
|
detail.Offset(-originX, -originY);
|
||
|
|
|
||
|
|
PathD pathBorder = new PathD();
|
||
|
|
foreach (var pt in detail.Outers[0].Points)
|
||
|
|
{
|
||
|
|
pathBorder.Add(new Clipper2Lib.PointD(pt.X, pt.Y));
|
||
|
|
}
|
||
|
|
|
||
|
|
// 加载断层数据
|
||
|
|
RawDetail detailFault = loadLayersDetail(this.FaultLayer);// loadDetail(this.faultageFile);
|
||
|
|
double dAreaFault = 0;
|
||
|
|
if (detailFault.Outers?.Count > 0)
|
||
|
|
{
|
||
|
|
detailFault.Offset(-originX, -originY);
|
||
|
|
PathsD paths = new PathsD(), solution;
|
||
|
|
double dMinFaultLength = CaculateParameter.MiniFaultLength;
|
||
|
|
foreach (var contour in detailFault.Outers)
|
||
|
|
{
|
||
|
|
// 忽略小断层
|
||
|
|
if (this.CaculateParameter.IgnoreMiniFault)
|
||
|
|
{
|
||
|
|
if (contour.Len <= dMinFaultLength)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
PathD path = new PathD();
|
||
|
|
bool bOutBorder = true;
|
||
|
|
foreach (var pt in contour.Points)
|
||
|
|
{
|
||
|
|
Clipper2Lib.PointD ptd = new Clipper2Lib.PointD(pt.X, pt.Y);
|
||
|
|
if (Clipper2Lib.Clipper.PointInPolygon(ptd, pathBorder) == PointInPolygonResult.IsInside)
|
||
|
|
{
|
||
|
|
bOutBorder = false; // 一旦有一个点在内部,则线不在边界外部
|
||
|
|
}
|
||
|
|
path.Add(new Clipper2Lib.PointD(pt.X, pt.Y));
|
||
|
|
}
|
||
|
|
// 排除边界外断层
|
||
|
|
if (bOutBorder == false)
|
||
|
|
{
|
||
|
|
paths.Add(path);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// 断层线外扩成多边形,宽度可调
|
||
|
|
solution = Clipper.InflatePaths(paths, faultInflate, Clipper2Lib.JoinType.Round, Clipper2Lib.EndType.Round);
|
||
|
|
solution = Clipper.SimplifyPaths(solution, 2.5);
|
||
|
|
dAreaFault = Clipper2Lib.Clipper.Area(solution);
|
||
|
|
// 多边形添加到边界
|
||
|
|
foreach (var pathChild in solution)
|
||
|
|
{
|
||
|
|
LocalContour contourChild = new LocalContour();
|
||
|
|
foreach (var pt in pathChild)
|
||
|
|
{
|
||
|
|
contourChild.Points.Add(new PointF((float)pt.x, (float)pt.y));
|
||
|
|
}
|
||
|
|
detail.Outers.Add(contourChild);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//bbox = detail.BoundingBox();
|
||
|
|
|
||
|
|
// 二次部井
|
||
|
|
if (this.WellParameters.DeployAgain)
|
||
|
|
{
|
||
|
|
// 加载井组数据
|
||
|
|
RawDetail detailWells = loadWellGroupDetail("井组");
|
||
|
|
// 相对原点进行坐标偏移
|
||
|
|
detailWells.Offset(-originX, -originY);
|
||
|
|
// 区域外扩
|
||
|
|
PathsD paths = new PathsD(), solution;
|
||
|
|
foreach (var contour in detailWells.Outers)
|
||
|
|
{
|
||
|
|
PathD path = new PathD();
|
||
|
|
bool bOutBorder = true;
|
||
|
|
foreach (var pt in contour.Points)
|
||
|
|
{
|
||
|
|
Clipper2Lib.PointD ptd = new Clipper2Lib.PointD(pt.X, pt.Y);
|
||
|
|
if (Clipper2Lib.Clipper.PointInPolygon(ptd, pathBorder) == PointInPolygonResult.IsInside)
|
||
|
|
{
|
||
|
|
bOutBorder = false; // 一旦有一个点在内部,则线不在边界外部
|
||
|
|
}
|
||
|
|
path.Add(new Clipper2Lib.PointD(pt.X, pt.Y));
|
||
|
|
}
|
||
|
|
// 排除边界外断层
|
||
|
|
if (bOutBorder == false)
|
||
|
|
{
|
||
|
|
if (Math.Abs(path.First().x - path.Last().x) > 1E-4 || Math.Abs(path.First().y - path.Last().y) > 1E-4)
|
||
|
|
{
|
||
|
|
path.Add(new Clipper2Lib.PointD(path.First().x, path.First().y));
|
||
|
|
}
|
||
|
|
paths.Add(path);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// 断层线外扩成多边形,宽度可调
|
||
|
|
solution = Clipper.InflatePaths(paths, this.partSpacing * 0.5, JoinType.Miter, EndType.Polygon);
|
||
|
|
solution = Clipper.SimplifyPaths(solution, 2.5);
|
||
|
|
|
||
|
|
// 统计约束区面积
|
||
|
|
dAreaFault += Clipper2Lib.Clipper.Area(solution);
|
||
|
|
|
||
|
|
// 多边形添加到边界
|
||
|
|
foreach (var pathChild in solution)
|
||
|
|
{
|
||
|
|
LocalContour contourChild = new LocalContour();
|
||
|
|
foreach (var pt in pathChild)
|
||
|
|
{
|
||
|
|
contourChild.Points.Add(new PointF((float)pt.x, (float)pt.y));
|
||
|
|
}
|
||
|
|
detail.Outers.Add(contourChild);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
NFP nfp = detail.ToNfp();
|
||
|
|
nest = new NestingContext();
|
||
|
|
int src = nest.GetNextSheetSource();
|
||
|
|
var ns = Background.clone(nfp);
|
||
|
|
Sheet sheet = new Sheet();
|
||
|
|
sheet.Points = ns.Points;
|
||
|
|
sheet.children = ns.children;
|
||
|
|
nest.Sheets.Add(sheet);
|
||
|
|
sheet.Width = sheet.WidthCalculated;
|
||
|
|
sheet.Height = sheet.HeightCalculated;
|
||
|
|
sheet.source = src;
|
||
|
|
|
||
|
|
nest.ReorderSheets();
|
||
|
|
|
||
|
|
// 边界的面积
|
||
|
|
double dAreaBorder = Clipper2Lib.Clipper.Area(pathBorder);
|
||
|
|
|
||
|
|
// 生成双侧井组
|
||
|
|
DrawerWellGroup wellGroupSide2 = new DrawerWellGroup();
|
||
|
|
|
||
|
|
this.groupParaSide2 = new WellGroupParameter();
|
||
|
|
this.groupParaSide2.WellPoint.X = 0;
|
||
|
|
this.groupParaSide2.WellPoint.Y = 0;
|
||
|
|
this.groupParaSide2.WellPoint.Z = 0;
|
||
|
|
this.groupParaSide2.WellPoint.Name = this.WellParameters.WellNamePrefix;
|
||
|
|
wellGroupSide2.Name = this.WellParameters.WellNamePrefix;
|
||
|
|
|
||
|
|
this.groupParaSide2.BranchDistanceRight = this.WellParameters.BranchOffset;
|
||
|
|
this.groupParaSide2.BranchDistanceLeft = this.groupParaSide2.BranchDistanceRight;
|
||
|
|
this.groupParaSide2.BranchAngle = 0.0;
|
||
|
|
this.groupParaSide2.BranchSpace = this.WellParameters.BranchSpace;
|
||
|
|
this.groupParaSide2.BranchLength = this.WellParameters.BranchLength;
|
||
|
|
this.groupParaSide2.BranchCountRight = this.WellParameters.BranchCount;
|
||
|
|
this.groupParaSide2.BranchCountLeft = this.groupParaSide2.BranchCountRight;
|
||
|
|
|
||
|
|
wellGroupSide2.Parameter = this.groupParaSide2.Clone();
|
||
|
|
bool bSuccess = wellGroupSide2.CreateHorizionWells();
|
||
|
|
// 生成单侧井组
|
||
|
|
this.groupParaSide1 = this.groupParaSide2.Clone();
|
||
|
|
this.groupParaSide1.BranchCountLeft = 0;
|
||
|
|
DrawerWellGroup wellGroupSide1 = new DrawerWellGroup();
|
||
|
|
wellGroupSide1.Parameter = groupParaSide1.Clone();
|
||
|
|
wellGroupSide1.CreateHorizionWells();
|
||
|
|
|
||
|
|
wellBox2 = CreateWellGroupBorder(wellGroupSide2, this.partSpacing);
|
||
|
|
wellBox1 = CreateWellGroupBorder(wellGroupSide1, this.partSpacing);
|
||
|
|
|
||
|
|
//List<RawDetail> shapes = new List<RawDetail>();
|
||
|
|
int nCountSide2 = 0;
|
||
|
|
if (this.WellParameters.DeploySide2 == true)
|
||
|
|
{
|
||
|
|
RawDetail detail2 = new RawDetail();
|
||
|
|
detail2.Outers.Add(wellBox2);
|
||
|
|
detail2.Name = "双侧";
|
||
|
|
|
||
|
|
PathD pathSide2 = new PathD();
|
||
|
|
|
||
|
|
foreach (var pt in wellBox2.Points)
|
||
|
|
{
|
||
|
|
pathSide2.Add(new Clipper2Lib.PointD(pt.X, pt.Y));
|
||
|
|
}
|
||
|
|
double dAreaSide2 = Clipper2Lib.Clipper.Area(pathSide2);
|
||
|
|
|
||
|
|
nCountSide2 = (int)Math.Abs((Math.Abs(dAreaBorder) - Math.Abs(dAreaFault)) / dAreaSide2);
|
||
|
|
for (int i = 0; i < nCountSide2; i++)
|
||
|
|
{
|
||
|
|
nest.ImportFromRawDetail(detail2, 0);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (WellParameters.DeploySide1 == true)
|
||
|
|
{
|
||
|
|
RawDetail detail1 = new RawDetail();
|
||
|
|
detail1.Outers.Add(wellBox1);
|
||
|
|
detail1.Name = "单侧";
|
||
|
|
// 根据不同情况计算单侧方式井部署的数量
|
||
|
|
if (this.WellParameters.DeploySide2 == true)
|
||
|
|
{
|
||
|
|
int nCountSide1 = (int)(nCountSide2 * 0.35);
|
||
|
|
for (int i = 0; i < nCountSide1; i++)
|
||
|
|
{
|
||
|
|
nest.ImportFromRawDetail(detail1, 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{
|
||
|
|
PathD pathSide1 = new PathD();
|
||
|
|
foreach (var pt in wellBox1.Points)
|
||
|
|
{
|
||
|
|
pathSide1.Add(new Clipper2Lib.PointD(pt.X, pt.Y));
|
||
|
|
}
|
||
|
|
double dAreaSide1 = Clipper2Lib.Clipper.Area(pathSide1);
|
||
|
|
int nCountSide1 = (int)Math.Abs((Math.Abs(dAreaBorder) - Math.Abs(dAreaFault)) / dAreaSide1);
|
||
|
|
for (int i = 0; i < nCountSide1; i++)
|
||
|
|
{
|
||
|
|
nest.ImportFromRawDetail(detail1, 1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
// 设置突变率
|
||
|
|
nestConfig.mutationRate = (int)(nest.Polygons.Count * this.CaculateParameter.MutationRate);
|
||
|
|
|
||
|
|
nest.ReorderSheets();
|
||
|
|
nest.Config = this.nestConfig;
|
||
|
|
IsStop = false;
|
||
|
|
return run();
|
||
|
|
}
|
||
|
|
private bool run()
|
||
|
|
{
|
||
|
|
if (nest.Polygons.Count == 0 || nest.Sheets.Count == 0)
|
||
|
|
{
|
||
|
|
//MessageBox.Show("There are no sheets or parts", Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
|
||
|
|
IsStop = true;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
Background.UseParallel = true;
|
||
|
|
|
||
|
|
GeneticAlgorithm.StrictAngles = false;
|
||
|
|
|
||
|
|
return RunDeepnest();
|
||
|
|
}
|
||
|
|
Thread th;
|
||
|
|
//internal void displayProgress(float progress)
|
||
|
|
//{
|
||
|
|
// // progressVal = progress;
|
||
|
|
//}
|
||
|
|
|
||
|
|
private bool RunDeepnest()
|
||
|
|
{
|
||
|
|
if (th != null) return false;
|
||
|
|
|
||
|
|
//--nest.DisplayProgressAction = DisplayProgressAction;
|
||
|
|
th = new Thread(() =>
|
||
|
|
{
|
||
|
|
nest.StartNest();
|
||
|
|
//UpdateNestsList();
|
||
|
|
//Background.DisplayProgressAction = displayProgress;
|
||
|
|
|
||
|
|
while (true)
|
||
|
|
{
|
||
|
|
this.Status = CaculateStatus.Paused;
|
||
|
|
if (IsStop)
|
||
|
|
{
|
||
|
|
//btnPlay.Enabled = true;
|
||
|
|
this.Status = CaculateStatus.Stopped;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// 根据是否收到信号判断是否阻塞当前线程
|
||
|
|
ma.WaitOne();
|
||
|
|
if (IsStop)
|
||
|
|
{
|
||
|
|
this.Status = CaculateStatus.Stopped;
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
Stopwatch sw = new Stopwatch();
|
||
|
|
sw.Start();
|
||
|
|
this.Status = CaculateStatus.Working;
|
||
|
|
nest.NestIterate();
|
||
|
|
//UpdatePreview();
|
||
|
|
//UpdateNestsList();
|
||
|
|
|
||
|
|
//--DisplayProgressAction(1.0f);
|
||
|
|
sw.Stop();
|
||
|
|
// string strInfo = $"利用率: {Math.Round(nest.MaterialUtilization * 100.0f, 2)}% 计算耗时: {sw.ElapsedMilliseconds}ms";
|
||
|
|
// writeUiSafe(strInfo);
|
||
|
|
IterateEvent?.Invoke(nest.Nest.nests, nest.MaterialUtilization, sw.ElapsedMilliseconds);
|
||
|
|
if (ExportPlaceMentsEvent != null)
|
||
|
|
{
|
||
|
|
ExportPlaceMents();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
th = null;
|
||
|
|
});
|
||
|
|
th.IsBackground = true;
|
||
|
|
th.Start();
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
private bool isDrawing = false;
|
||
|
|
/// <summary>
|
||
|
|
/// 生成部署图和部署信息
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="placementIndex">方案的索引</param>
|
||
|
|
/// <param name="image">输出的部署图片</param>
|
||
|
|
/// <param name="info">输出的部署信息</param>
|
||
|
|
/// <returns></returns>
|
||
|
|
public bool CreatePlacementImage(int placementIndex, out Bitmap image, out string info)
|
||
|
|
{
|
||
|
|
if(nest.Nest.nests.Count<= placementIndex)
|
||
|
|
{
|
||
|
|
image = null;
|
||
|
|
info = null;
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
SheetPlacement placement = nest.Nest.nests[placementIndex];
|
||
|
|
nest.AssignPlacement(placement);
|
||
|
|
|
||
|
|
if(exportPlacementImage(out image, out info))
|
||
|
|
{
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 生成部署图和部署信息
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="image"></param>
|
||
|
|
/// <param name="info"></param>
|
||
|
|
/// <returns></returns>
|
||
|
|
private bool exportPlacementImage(out Bitmap image, out string info)
|
||
|
|
{
|
||
|
|
image = null;
|
||
|
|
info = null;
|
||
|
|
if (isDrawing)
|
||
|
|
{
|
||
|
|
return false;
|
||
|
|
}
|
||
|
|
isDrawing = true;
|
||
|
|
|
||
|
|
StringBuilder strbStatistic = new StringBuilder();
|
||
|
|
foreach (var kv in nest.PartsStatistic)
|
||
|
|
{
|
||
|
|
strbStatistic.Append($"{kv.Key}:{kv.Value}个 ");
|
||
|
|
}
|
||
|
|
info = $"覆盖率: {Math.Round(nest.MaterialUtilization * 100.0f, 2)}% {strbStatistic}";
|
||
|
|
CoverageRate = Math.Round(nest.MaterialUtilization * 100.0f, 2);
|
||
|
|
addSymbols(drawer);
|
||
|
|
// 删除已有井组
|
||
|
|
if (this.WellParameters.DeploySide2 == true)
|
||
|
|
{
|
||
|
|
//drawer.DeleteLayer(new string[1] { "井组\\双侧" }, true);
|
||
|
|
drawer.DeleteLayerElement( "井组\\双侧" , true);
|
||
|
|
}
|
||
|
|
if (this.WellParameters.DeploySide1 == true)
|
||
|
|
{
|
||
|
|
drawer.DeleteLayerElement("井组\\单侧", true);
|
||
|
|
//drawer.DeleteLayer(new string[1] { "井组\\单侧" }, true);
|
||
|
|
}
|
||
|
|
//drawer.DeleteLayerElement( "井组" , true);
|
||
|
|
// 部件内缩距离
|
||
|
|
float fSpace = (float)(partSpacing * 0.5);
|
||
|
|
// 断层外扩距离
|
||
|
|
float fFaultExpand = fSpace;
|
||
|
|
List<PointF> box1 = new List<PointF>();
|
||
|
|
box1.AddRange(new PointF[5] {
|
||
|
|
new PointF(wellBox1.Points[0].X+fSpace, wellBox1.Points[0].Y+fSpace),
|
||
|
|
new PointF(wellBox1.Points[1].X-fSpace, wellBox1.Points[1].Y+fSpace),
|
||
|
|
new PointF(wellBox1.Points[2].X-fSpace, wellBox1.Points[2].Y-fSpace),
|
||
|
|
new PointF(wellBox1.Points[3].X+fSpace, wellBox1.Points[3].Y-fSpace),
|
||
|
|
new PointF(wellBox1.Points[4].X+fSpace, wellBox1.Points[4].Y+fSpace) });
|
||
|
|
List<PointF> box2 = new List<PointF>();
|
||
|
|
box2.AddRange(new PointF[] {
|
||
|
|
new PointF(wellBox2.Points[0].X+fSpace, wellBox2.Points[0].Y+fSpace),
|
||
|
|
new PointF(wellBox2.Points[1].X-fSpace, wellBox2.Points[1].Y+fSpace),
|
||
|
|
new PointF(wellBox2.Points[2].X-fSpace, wellBox2.Points[2].Y-fSpace),
|
||
|
|
new PointF(wellBox2.Points[3].X+fSpace, wellBox2.Points[3].Y-fSpace),
|
||
|
|
new PointF(wellBox2.Points[4].X+fSpace, wellBox2.Points[4].Y+fSpace)});
|
||
|
|
//this.resultFile = this.txtResultFile.Text;
|
||
|
|
//string strExt = Path.GetExtension(resultFile).ToUpper();
|
||
|
|
|
||
|
|
List<Tuple<NFP, int>> lstWells = new List<Tuple<NFP, int>>();
|
||
|
|
|
||
|
|
HashSet<int> removedIndices = DfdParser.ExportPlacements(nest.Polygons, nest.Sheets.ToArray(), this.originX, this.originY, (polygon, wellType) =>
|
||
|
|
{
|
||
|
|
// 断层外扩处理
|
||
|
|
if (wellType == 2) //strName == "断层")
|
||
|
|
{
|
||
|
|
PathsD paths = new PathsD(), solution;
|
||
|
|
PathD path = new PathD();
|
||
|
|
foreach (var pt in polygon.Points)
|
||
|
|
{
|
||
|
|
path.Add(new Clipper2Lib.PointD(pt.x, pt.y));
|
||
|
|
}
|
||
|
|
paths.Add(path);
|
||
|
|
|
||
|
|
// 断层线外扩成多边形,宽度可调
|
||
|
|
solution = Clipper.InflatePaths(paths, fFaultExpand, JoinType.Round, EndType.Round);
|
||
|
|
solution = Clipper.SimplifyPaths(solution, 2.5);
|
||
|
|
if (solution.Count > 0)
|
||
|
|
{
|
||
|
|
PointF[] pts = solution[0].Select(it => new PointF((float)it.x, (float)it.y)).ToArray();
|
||
|
|
return pts;
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
}
|
||
|
|
else if (wellType == 0) //strName.Equals("双侧"))
|
||
|
|
{
|
||
|
|
lstWells.Add(new Tuple<NFP, int>(polygon, wellType));
|
||
|
|
// polygon内缩处理
|
||
|
|
return box2.ToArray();
|
||
|
|
}
|
||
|
|
else if (wellType == 1) //strName.Equals("单侧"))
|
||
|
|
{
|
||
|
|
lstWells.Add(new Tuple<NFP, int>(polygon, wellType));
|
||
|
|
return box1.ToArray();
|
||
|
|
}
|
||
|
|
return null;
|
||
|
|
});
|
||
|
|
if (lstWells.Count > 0)
|
||
|
|
{
|
||
|
|
SingleWell = 0;// 计数器清零
|
||
|
|
DoubleWell = 0;// 计数器清零
|
||
|
|
string strWellName = this.WellParameters.WellNamePrefix;
|
||
|
|
//DrawerData drawer = new DrawerData();
|
||
|
|
for (int i = 0; i < lstWells.Count; i++)
|
||
|
|
{
|
||
|
|
if (removedIndices.Contains(i)) { continue; }
|
||
|
|
Tuple<NFP, int> well = lstWells[i];
|
||
|
|
string strElementData = string.Empty;
|
||
|
|
if (well.Item2 == 0)
|
||
|
|
{ // 双侧井组
|
||
|
|
DrawerWellGroup wellGroupSide2 = new DrawerWellGroup();
|
||
|
|
wellGroupSide2.Parameter = this.groupParaSide2.Clone();
|
||
|
|
wellGroupSide2.Parameter.BranchAngle = well.Item1.rotation;
|
||
|
|
wellGroupSide2.Name = $"{strWellName}{i + 1}";
|
||
|
|
wellGroupSide2.CreateHorizionWells();
|
||
|
|
setWellGroupStyle(wellGroupSide2);
|
||
|
|
|
||
|
|
wellGroupSide2.Offset(this.originX, this.originY);
|
||
|
|
wellGroupSide2.Offset(well.Item1.x, well.Item1.y);
|
||
|
|
DrawerElementProperty element = new DrawerElementProperty();
|
||
|
|
element.Element = wellGroupSide2;
|
||
|
|
element.ElementType = wellGroupSide2.ElementType;
|
||
|
|
strElementData = DrawerElementHelp.Serialize(element);
|
||
|
|
drawer.AddWellGroup("井组\\双侧", strElementData);
|
||
|
|
DoubleWell++;
|
||
|
|
}
|
||
|
|
else
|
||
|
|
{ // 单侧井组
|
||
|
|
//wellGroupSide1.Angle = well.Item1.rotation + 90;
|
||
|
|
DrawerWellGroup wellGroupSide1 = new DrawerWellGroup();
|
||
|
|
wellGroupSide1.Name = $"{strWellName}{i + 1}";
|
||
|
|
wellGroupSide1.Parameter = this.groupParaSide1.Clone();
|
||
|
|
wellGroupSide1.Parameter.BranchAngle = well.Item1.rotation;
|
||
|
|
|
||
|
|
wellGroupSide1.CreateHorizionWells();
|
||
|
|
setWellGroupStyle(wellGroupSide1);
|
||
|
|
wellGroupSide1.Offset(this.originX, this.originY);
|
||
|
|
wellGroupSide1.Offset(well.Item1.x, well.Item1.y);
|
||
|
|
DrawerElementProperty element = new DrawerElementProperty();
|
||
|
|
element.Element = wellGroupSide1;
|
||
|
|
element.ElementType = wellGroupSide1.ElementType;
|
||
|
|
strElementData = DrawerElementHelp.Serialize(element);
|
||
|
|
drawer.AddWellGroup("井组\\单侧", strElementData);
|
||
|
|
SingleWell++;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
IntPtr hBmp = drawer.GetBitmapHandle(this.ImageWidth, this.ImageHeight, 0);
|
||
|
|
image = System.Drawing.Image.FromHbitmap(hBmp);
|
||
|
|
image.MakeTransparent(Color.White);
|
||
|
|
//this.pictureBox1.Image = bmp;
|
||
|
|
drawer.DeleteHbmp(hBmp);
|
||
|
|
//this.ExportPlaceMentsEvent?.Invoke(bmp, strInfo);
|
||
|
|
isDrawing = false;
|
||
|
|
return true;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 导出部署图
|
||
|
|
/// </summary>
|
||
|
|
private void ExportPlaceMents()
|
||
|
|
{
|
||
|
|
if(exportPlacementImage(out Bitmap image, out string info))
|
||
|
|
{
|
||
|
|
this.ExportPlaceMentsEvent?.Invoke(image, info);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 设置进组的显示样式
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="wellGroup">井组</param>
|
||
|
|
private void setWellGroupStyle(DrawerWellGroup wellGroup)
|
||
|
|
{
|
||
|
|
// 设置井点样式
|
||
|
|
DrawerPointStyle ptstyleWell = new DrawerPointStyle();
|
||
|
|
ptstyleWell.AlignHorizion = (int)TextStyleFlags.alignCenterH;
|
||
|
|
ptstyleWell.AlignVertical = (int)TextStyleFlags.alignTop;
|
||
|
|
ptstyleWell.Offset = new PropertyPoint(0, 50);
|
||
|
|
|
||
|
|
PropertySize txtSize = default(PropertySize);
|
||
|
|
txtSize.Width = 100 * 0.4;
|
||
|
|
txtSize.Height = 100;
|
||
|
|
txtSize.FixScale = true;
|
||
|
|
|
||
|
|
SizeF sizeSymbol = new SizeF(100f, 100f);
|
||
|
|
|
||
|
|
ptstyleWell.TextSize = txtSize;
|
||
|
|
ptstyleWell.SymbolSize = sizeSymbol;
|
||
|
|
ptstyleWell.SymbolName = "井点";
|
||
|
|
wellGroup.WellPointStyle = ptstyleWell;
|
||
|
|
|
||
|
|
// 设置井支入靶点和出靶点样式
|
||
|
|
DrawerPointStyle ptStart = ptstyleWell.Clone();
|
||
|
|
ptStart.Name = "start";
|
||
|
|
ptStart.SymbolName = "入靶点";
|
||
|
|
ptStart.SymbolSize = new SizeF((float)(sizeSymbol.Width * 0.5), (float)(sizeSymbol.Height * 0.5));
|
||
|
|
|
||
|
|
DrawerPointStyle ptEnd = ptstyleWell.Clone();
|
||
|
|
ptEnd.Name = "end";
|
||
|
|
ptEnd.SymbolName = "出靶点";
|
||
|
|
ptEnd.SymbolSize = new SizeF((float)(sizeSymbol.Width * 0.5), (float)(sizeSymbol.Height * 0.5));
|
||
|
|
|
||
|
|
|
||
|
|
DrawerCurveStyle drawerCurveStyleOffset = new DrawerCurveStyle();
|
||
|
|
drawerCurveStyleOffset.Name = "offset";
|
||
|
|
|
||
|
|
CurveProperty curvePropertyOffset = new CurveProperty();
|
||
|
|
curvePropertyOffset.Width = 5;
|
||
|
|
curvePropertyOffset.LineColor = Color.Black;
|
||
|
|
drawerCurveStyleOffset.Properties.Add(curvePropertyOffset);
|
||
|
|
|
||
|
|
DrawerCurveStyle drawerCurveStyleHori = new DrawerCurveStyle();
|
||
|
|
drawerCurveStyleHori.Name = "horizon";
|
||
|
|
CurveProperty curvePropertyHori = new CurveProperty();
|
||
|
|
curvePropertyHori.Width = 5;
|
||
|
|
curvePropertyHori.LineColor = Color.Black;
|
||
|
|
drawerCurveStyleHori.Properties.Add(curvePropertyHori);
|
||
|
|
|
||
|
|
List<DrawerCurveStyle> lineStyles = new List<DrawerCurveStyle>
|
||
|
|
{
|
||
|
|
drawerCurveStyleOffset,
|
||
|
|
drawerCurveStyleHori
|
||
|
|
};
|
||
|
|
|
||
|
|
int nBranchAllCount = wellGroup.WellBranches.Count;
|
||
|
|
for (int i = 0; i < nBranchAllCount; i++)
|
||
|
|
{
|
||
|
|
WellBranch branch = wellGroup.WellBranches[i];
|
||
|
|
branch.PointStyles = new List<DrawerPointStyle>
|
||
|
|
{
|
||
|
|
ptStart,
|
||
|
|
ptEnd
|
||
|
|
};
|
||
|
|
|
||
|
|
branch.PointStart.Name = $"{wellGroup.Name}-{i + 1}A";
|
||
|
|
branch.PointEnd.Name = $"{wellGroup.Name}-{i + 1}B";
|
||
|
|
|
||
|
|
branch.LineStyles = lineStyles;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 添加进组所需符号
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="drawer"></param>
|
||
|
|
private void addSymbols(DrawerData drawer)
|
||
|
|
{
|
||
|
|
string strSymbolWell = @"Layer M 0
|
||
|
|
Pline
|
||
|
|
-0.5,-0.5
|
||
|
|
-0.5,0.5
|
||
|
|
0.5,0.5
|
||
|
|
0.5,-0.5
|
||
|
|
-0.5,-0.5
|
||
|
|
";
|
||
|
|
drawer.AddDataAsSymble(strSymbolWell, "井点", false);
|
||
|
|
|
||
|
|
strSymbolWell = @"Layer M 0
|
||
|
|
_Ellipse
|
||
|
|
0,0
|
||
|
|
0.5,0.5
|
||
|
|
0.5 4
|
||
|
|
";
|
||
|
|
drawer.AddDataAsSymble(strSymbolWell, "入靶点", false);
|
||
|
|
|
||
|
|
strSymbolWell = @"Layer M 0
|
||
|
|
_Ellipse
|
||
|
|
0,0
|
||
|
|
0.5,0.5
|
||
|
|
0.5 4
|
||
|
|
";
|
||
|
|
drawer.AddDataAsSymble(strSymbolWell, "出靶点", false);
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 加载线数据
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="layers"></param>
|
||
|
|
/// <returns></returns>
|
||
|
|
private RawDetail loadLayersDetail(string layers)
|
||
|
|
{
|
||
|
|
string[] saFullLayers = Regex.Split(layers, ",");
|
||
|
|
RawDetail rawDetail = new RawDetail();
|
||
|
|
// 遍历每一个图层
|
||
|
|
foreach (string layer in saFullLayers)
|
||
|
|
{
|
||
|
|
string curveData = string.Empty;
|
||
|
|
int nCount = drawer.LayerGetCurves(layer, ref curveData, false);
|
||
|
|
if (nCount == 0)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
DrawerElementHelp elementHelp = new DrawerElementHelp();
|
||
|
|
List<DrawerElementProperty> propertys = elementHelp.DeserializeList(curveData);
|
||
|
|
// 生成每一条线
|
||
|
|
foreach (DrawerElementProperty eleProperty in propertys)
|
||
|
|
{
|
||
|
|
DrawerPline blockLine = eleProperty.Element as DrawerPline;
|
||
|
|
if (blockLine == null)
|
||
|
|
{
|
||
|
|
continue;
|
||
|
|
}
|
||
|
|
string[] saCoorLine = Regex.Split(blockLine.Coordinate, "\r\n");
|
||
|
|
if (saCoorLine.Length > 1)
|
||
|
|
{
|
||
|
|
// 生成每一个坐标点
|
||
|
|
List<PointF> points = new List<PointF>();
|
||
|
|
foreach (string strLine in saCoorLine)
|
||
|
|
{
|
||
|
|
string[] saCoor = strLine.Split(',');
|
||
|
|
if (saCoor.Length > 1)
|
||
|
|
{
|
||
|
|
points.Add(new PointF(float.Parse(saCoor[0]), float.Parse(saCoor[1])));
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (points.Count > 0)
|
||
|
|
{
|
||
|
|
rawDetail.Outers.Add(new LocalContour() { Points = points });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
return rawDetail;
|
||
|
|
}
|
||
|
|
/// <summary>
|
||
|
|
/// 加载井组的轮廓数据
|
||
|
|
/// </summary>
|
||
|
|
/// <param name="layers"></param>
|
||
|
|
/// <returns></returns>
|
||
|
|
private RawDetail loadWellGroupDetail(string layers)
|
||
|
|
{
|
||
|
|
RawDetail rawDetail = new RawDetail();
|
||
|
|
long[] laPos = this.drawer.SearchElementByType((int)DrawElementType.ELEMENT_WELL_GROUP);
|
||
|
|
if(laPos == null)
|
||
|
|
{
|
||
|
|
return rawDetail;
|
||
|
|
}
|
||
|
|
foreach (long pos in laPos)
|
||
|
|
{
|
||
|
|
NFP nfpHull = new NFP();
|
||
|
|
List<SvgPoint> lstPt = new List<SvgPoint>();
|
||
|
|
|
||
|
|
string strElementData = this.drawer.GetElementByPosition(pos);
|
||
|
|
DrawerElementProperty property = DrawerElementHelp.Deserialize(strElementData);
|
||
|
|
DrawerWellGroup wellGroup = property.Element as DrawerWellGroup;
|
||
|
|
|
||
|
|
lstPt.Add(new SvgPoint(wellGroup.X, wellGroup.Y));
|
||
|
|
foreach (WellBranch branch in wellGroup.WellBranches)
|
||
|
|
{
|
||
|
|
lstPt.Add(new SvgPoint(branch.PointStart.X, branch.PointStart.Y));
|
||
|
|
lstPt.Add(new SvgPoint(branch.PointEnd.X, branch.PointEnd.Y));
|
||
|
|
}
|
||
|
|
nfpHull.Points = lstPt.ToArray();
|
||
|
|
NFP hull = Background.getHull(nfpHull);
|
||
|
|
|
||
|
|
LocalContour contourHull = new LocalContour();
|
||
|
|
contourHull.Points = new List<PointF>(hull.Points.Select(it => new PointF((float)it.x, (float)it.y)));
|
||
|
|
rawDetail.Outers.Add(contourHull);
|
||
|
|
}
|
||
|
|
|
||
|
|
return rawDetail;
|
||
|
|
}
|
||
|
|
private static LocalContour CreateWellGroupBorder(DrawerWellGroup wellGroup, double spacing)
|
||
|
|
{
|
||
|
|
RectangleD rect = wellGroup.CaculateDataRange();
|
||
|
|
float dSpacing = (float)(spacing * 0.5);
|
||
|
|
List<PointF> shapePoints = new List<PointF>();
|
||
|
|
shapePoints.AddRange(new PointF[5] {
|
||
|
|
new PointF((float)rect.Left-dSpacing, (float)rect.Top-dSpacing),
|
||
|
|
new PointF((float)rect.Right+dSpacing, (float)rect.Top-dSpacing),
|
||
|
|
new PointF((float)rect.Right+dSpacing, (float)rect.Bottom+dSpacing),
|
||
|
|
new PointF((float)rect.Left-dSpacing, (float)rect.Bottom+dSpacing),
|
||
|
|
new PointF((float)rect.Left-dSpacing, (float)rect.Top-dSpacing),
|
||
|
|
});
|
||
|
|
LocalContour contour = new LocalContour()
|
||
|
|
{
|
||
|
|
Points = shapePoints,
|
||
|
|
};
|
||
|
|
return contour;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
public enum CaculateStatus
|
||
|
|
{
|
||
|
|
None = 0,
|
||
|
|
Stopping =1,
|
||
|
|
Stopped = 2,
|
||
|
|
Pausing = 3,
|
||
|
|
Paused = 4,
|
||
|
|
Working =5,
|
||
|
|
}
|
||
|
|
}
|