using DevExpress.XtraEditors.Repository; using DevExpress.XtraVerticalGrid.Rows; using GeoSigmaDrawLib; using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Runtime.InteropServices; using System.Text; using System.Windows.Forms; //using Dector = OutlineDetectionUtil; namespace RiverPortray { /// /// 河道刻画主窗体. /// public partial class FormMain : DevExpress.XtraEditors.XtraForm { /// /// 模块进程名称 /// public static string ProcessName { get; set; } = "轮廓刻画"; public EventHandler PushDataClick; private IntPtr pXy = IntPtr.Zero; private bool isSyncing = false; // 用于防止事件循环 private bool isUserClick = true; private double GridZMin = 0; private double GridZMax = 100; /// /// Initializes a new instance of the class. /// public FormMain() { InitializeComponent(); this.Text = ProcessName; // Initialize the Qt Application (do not use DllMain for this) OutlineDetector.InitializeQtApplication(); IntPtr hWin = pcbView.Handle; OutlineDetector.EmbedQtWidget(hWin); } /// /// Initializes a new instance of the class. /// /// The p xy. public FormMain(IntPtr pXy) : this() { this.pXy = pXy; } /// /// 窗体加载事件. /// /// The sender. /// The e. private void FormMain_Load(object sender, EventArgs e) { if(this.pXy != IntPtr.Zero) { double dXMin = 0; double dYMin = 0; double dStepX = 0; double dStepY = 0; double dZMin = 0; double dZMax = 0; int nNumX = 0; int nNumY = 0; long lpValue = 0; bool bSuccess = DrawerData.XyGetMeshData(this.pXy, ref dXMin, ref dYMin, ref nNumX, ref nNumY, ref dStepX, ref dStepY, ref lpValue, ref dZMin, ref dZMax); if (bSuccess) { OutlineDetector.LoadGrid(nNumX, nNumY, dXMin, dYMin, dStepX, dStepY, lpValue, dZMin, dZMax); this.loadParameters(); } } } /// /// 窗体关闭事件. /// /// The e. protected override void OnFormClosed(FormClosedEventArgs e) { // Clean up Qt Application when the WinForms application closes OutlineDetector.ShutdownQtApplication(); base.OnFormClosed(e); } /// /// 打开文件事件. /// /// The sender. /// The e. private void bbtnOpenFile_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { OpenFileDialog ofd = new OpenFileDialog(); ofd.Filter = "*.dfg|*.dfg|*.keg|*.keg|*.*|*.*"; ofd.RestoreDirectory = true; if(ofd.ShowDialog() == DialogResult.OK) { string strFile = ofd.FileName; bool bResult = OutlineDetector.LoadGridFile(strFile); if(bResult == true) { loadParameters(); } } } /// /// 加载参数信息. /// private void loadParameters() { isUserClick = false; if (this.bbtnViewColorful.Down == false) { this.bbtnViewColorful.Down = true; } FaciesParameter par = this.GetFaciesParameter(); this.BindCaculatePara(par); GridParameter grdPar = GetGridParameter(); this.propertyGridControl1.SelectedObject = grdPar; isUserClick = true; } /// /// 绑定计算参数. /// /// The par. private void BindCaculatePara(FaciesParameter par) { isSyncing = true; this.txtZMin.Text = $"{par.ZMin:F4}"; this.txtZMax.Text = $"{par.ZMax:F4}"; double dZMin = 0; double dZMax = 0; if (OutlineDetector.GetSurfaceZRange(ref dZMin, ref dZMax)) { this.GridZMin = dZMin; this.GridZMax = dZMax; trackZMin.Properties.Minimum = 0; // (int)dZMin; trackZMin.Properties.Maximum = 100;// (int)dZMax; trackZMin.Value = (int)((par.ZMin- this.GridZMin) / (this.GridZMax- this.GridZMin)*100); trackZMax.Properties.Minimum = 0; trackZMax.Properties.Maximum = 100; trackZMax.Value = (int)((par.ZMax - this.GridZMin) / (this.GridZMax - this.GridZMin) * 100); } int dDialatMax = 0; if (OutlineDetector.GetDilateMax(ref dDialatMax)) { this.speDilate.Properties.MinValue = 0; this.speDilate.Properties.MaxValue = dDialatMax; this.speDilate.Value = 2; } this.txtAreaMin.Text = $"{par.AreaMin}"; this.txtSmoothTimes.Text = $"{par.SmoothTimes}"; isSyncing = false; } /// /// 窗体尺寸变化事件 /// /// The sender. /// The e. private void pcbView_SizeChanged(object sender, EventArgs e) { // Resize the Qt widget to match the size of the panel OutlineDetector.ResizeQtWidget(pcbView.Width, pcbView.Height); } /// /// 原图按钮点击事件. /// /// The sender. /// The e. private void bbtnViewColorful_DownChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { if (bbtnViewColorful.Down && isUserClick == true) { OutlineDetector.ViewColorful(); } this.bbtnPushBack.Enabled = bbtnCreateLines.Down; this.bbtnExportLines.Enabled = this.bbtnPushBack.Enabled; } /// /// 黑白图按钮点击事件. /// /// The sender. /// The e. private void bbtnViewBlackWhite_DownChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { this.ViewInBlackBlack(); this.bbtnPushBack.Enabled = bbtnCreateLines.Down; this.bbtnExportLines.Enabled = this.bbtnPushBack.Enabled; } /// /// Views the in black black. /// private void ViewInBlackBlack() { if (bbtnViewBlackWhite.Down) { OutlineDetector.ViewBlackWhite(); } } /// /// 生成轮廓线. /// private void ReCreateLines() { if (this.bbtnCreateLines.Down) { OutlineDetector.CreateLines(); } } /// /// 生成刻画线事件. /// /// The sender. /// The e. private void bbtnCreateLines_DownChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { ReCreateLines(); this.bbtnPushBack.Enabled = bbtnCreateLines.Down; this.bbtnExportLines.Enabled = this.bbtnPushBack.Enabled; } /// /// Gets the 刻画参数信息. /// /// A FaciesParameter. private FaciesParameter GetFaciesParameter() { FaciesParameter par = new FaciesParameter(); par.ZMin= OutlineDetector.GetFaciesZMin(); par.ZMax = OutlineDetector.GetFaciesZMax(); par.Dilate = OutlineDetector.GetDilate(); par.AreaMin = OutlineDetector.GetFaciesAreaMin(); par.SmoothTimes = OutlineDetector.GetFaciesSmoothTimes(); return par; } /// /// 获取网格信息. /// /// A GridParameter. private GridParameter GetGridParameter() { GridParameter par = new GridParameter(); int xNum = 0; int yNum = 0; double deltaX = 0; double deltaY = 0; double zMin = 0; double zMax = 0; OutlineDetector.GetSurfaceParameter(ref xNum, ref yNum, ref deltaX, ref deltaY, ref zMin, ref zMax); par.XNum = xNum; par.YNum = yNum; par.DeltX = deltaX; par.DeltY = deltaY; par.ZMin = zMin; par.ZMax = zMax; return par; } /// /// properties the grid control1_ custom row created. /// /// The sender. /// The e. private void propertyGridControl1_CustomRowCreated(object sender, DevExpress.XtraVerticalGrid.Events.CustomRowCreatedEventArgs e) { if(e.Row is PGridNumericEditorRow numRow) { // 创建并配置 RepositoryItemTextEdit RepositoryItemTextEdit textEdit = new RepositoryItemTextEdit(); textEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric; textEdit.DisplayFormat.FormatString = "F2"; // 保留两位小数,"F3" 表示保留三位小数 textEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric; textEdit.EditFormat.FormatString = "F2"; // 编辑时保留两位小数 // 将 RepositoryItemTextEdit 赋给该行 numRow.Properties.RowEdit = textEdit; } //if (e.Row.Properties.FieldName == "ZMin" // || e.Row.Properties.FieldName == "ZMax") //{ // SetupRowZ(e.Row as PGridNumericEditorRow); //} //else if (e.Row.Properties.FieldName == "Dilate") //{ // int dDialatMax = 0; // if (OutlineDetector.GetDilateMax(ref dDialatMax)) // { // ((PGridNumericEditorRow)e.Row).MaxValue = dDialatMax; // } //} } /// /// Setups the row z. /// /// The row. protected void SetupRowZ(PGridNumericEditorRow row) { double dZMin = 0; double dZMax = 0; if (OutlineDetector.GetSurfaceZRange(ref dZMin, ref dZMax)) { row.MinValue = -(int)dZMax; row.MaxValue = -(int)dZMin; //// 显式创建并设置 SpinEdit 编辑器 //RepositoryItemSpinEdit spinEdit = new RepositoryItemSpinEdit //{ // MinValue = (decimal)dZMin, // MaxValue = (decimal)dZMax //}; // 显式创建并设置 TrackBar 编辑器 RepositoryItemTrackBar trackBarEdit = new RepositoryItemTrackBar { Minimum = (int)dZMin, // TrackBar 只能接受整数 Maximum = (int)dZMax // 设置负数范围的最大值 }; // 将自定义的 SpinEdit 分配给行 row.Properties.RowEdit = trackBarEdit; row.ShowTrackBar = true; } } public class FixPGridNumericEditorRow: PGridNumericEditorRow { public FixPGridNumericEditorRow() : base() { } protected override Size CalcEditorSize() { if (!ShowTrackBar) { return base.CalcEditorSize(); } int nWidth = Math.Max(60, base.Grid.ViewInfo.ViewRects.ScrollableRectangle.Width / 5); return new Size(nWidth, base.Grid.OptionsView.MinRowAutoHeight); } } /// /// properties the grid control1_ custom property descriptors. /// /// The sender. /// The e. private void propertyGridControl1_CustomPropertyDescriptors(object sender, DevExpress.XtraVerticalGrid.Events.CustomPropertyDescriptorsEventArgs e) { e.Properties = e.Properties.Sort(new string[] { "ZMin", "ZMax", "Dilate", "AreaMin", "SmoothTimes" }); } /// /// txts the z min_ edit value changed. /// /// The sender. /// The e. private void txtZMin_EditValueChanged(object sender, EventArgs e) { if(isSyncing == false) { isSyncing = true;// 防止事件循环 double newValue; if (double.TryParse(txtZMin.Text, out newValue)) { // 设置 TrackBarControl 的值,且值必须在其范围内 if (newValue >= this.GridZMin && newValue <= this.GridZMax) { trackZMin.Value = (int)((newValue-this.GridZMin)/(this.GridZMax-this.GridZMin)*100); OutlineDetector.SetFaciesZMin(newValue); // 重新生成轮廓 ReCreateLines(); ViewInBlackBlack(); } } isSyncing = false; } } /// /// tracks the z min_ edit value changed. /// /// The sender. /// The e. private void trackZMin_EditValueChanged(object sender, EventArgs e) { if (!isSyncing) { isSyncing = true; // 防止事件循环 double zValue = (trackZMin.Value / 100.0) * (this.GridZMax - this.GridZMin) + this.GridZMin; txtZMin.Text = zValue.ToString("F4"); OutlineDetector.SetFaciesZMin(zValue); // 重新生成轮廓 ReCreateLines(); ViewInBlackBlack(); isSyncing = false; } } /// /// txts the z max_ edit value changed. /// /// The sender. /// The e. private void txtZMax_EditValueChanged(object sender, EventArgs e) { if (isSyncing == false) { isSyncing = true;// 防止事件循环 double newValue; if (double.TryParse(txtZMax.Text, out newValue)) { // 设置 TrackBarControl 的值,且值必须在其范围内 if (newValue >= this.GridZMin && newValue <= this.GridZMax) { trackZMax.Value = (int)((newValue - this.GridZMin) / (this.GridZMax - this.GridZMin) * 100); OutlineDetector.SetFaciesZMax(newValue); this.ReCreateLines(); this.ViewInBlackBlack(); } } isSyncing = false; } } /// /// tracks the z max_ edit value changed. /// /// The sender. /// The e. private void trackZMax_EditValueChanged(object sender, EventArgs e) { if (!isSyncing) { isSyncing = true; // 防止事件循环 double zValue = (trackZMax.Value / 100.0) * (this.GridZMax - this.GridZMin) + this.GridZMin; txtZMax.Text = zValue.ToString("F4"); OutlineDetector.SetFaciesZMax(zValue); this.ReCreateLines(); this.ViewInBlackBlack(); isSyncing = false; } } /// /// 膨胀系数数据变化事件. /// /// The sender. /// The e. private void speDilate_EditValueChanged(object sender, EventArgs e) { OutlineDetector.SetDilate((int)speDilate.Value); this.ReCreateLines(); } /// /// 最小面积修改事件. /// /// The sender. /// The e. private void txtAreaMin_EditValueChanged(object sender, EventArgs e) { double newValue; if (double.TryParse(txtAreaMin.Text, out newValue)) { OutlineDetector.SetFaciesAreaMin(newValue); this.ReCreateLines(); } } /// /// 平滑次数修改事件. /// /// The sender. /// The e. private void txtSmoothTimes_EditValueChanged(object sender, EventArgs e) { int newValue; if (int.TryParse(txtSmoothTimes.Text, out newValue)) { OutlineDetector.SetFaciesSmoothTimes(newValue); this.ReCreateLines(); } } private void propertyGridControl1_CustomRecordCellEdit(object sender, DevExpress.XtraVerticalGrid.Events.GetCustomRowCellEditEventArgs e) { //var editor = e.RepositoryItem; //if(editor is RepositoryItemTextEdit textEdit) //{ // textEdit.DisplayFormat.FormatType = DevExpress.Utils.FormatType.Numeric; // textEdit.DisplayFormat.FormatString = "F2"; // textEdit.EditFormat.FormatType = DevExpress.Utils.FormatType.Numeric; // textEdit.EditFormat.FormatString = "F2"; // 编辑时保留两位小数 //} } /// /// 导出轮廓线数据. /// /// The sender. /// The e. private void bbtnExportLines_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { SaveFileDialog ofd = new SaveFileDialog(); ofd.Filter = "*.kev|*.kev"; ofd.RestoreDirectory = true; ofd.OverwritePrompt = true; if (ofd.ShowDialog() == DialogResult.OK) { // 调用C++函数获取字符串 IntPtr messagePtr = OutlineDetector.GetContourData(); // 将IntPtr转换为C#的字符串 string message = Marshal.PtrToStringAnsi(messagePtr); OutlineDetector.DeletePointerArray(messagePtr); if (string.IsNullOrEmpty(message)) { MessageBox.Show("当前没有可以导出的数据!"); return; } DrawerData drawerData = new DrawerData(); drawerData.AddBufferData(message); drawerData.SaveAs(ofd.FileName); } } /// /// 数据回写点击事件. /// /// The sender. /// The e. private void bbtnPushBack_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { // 调用C++函数获取字符串 //IntPtr messagePtr = OutlineDetector.GetContourData(); IntPtr ptrPolygons = OutlineDetector.GetContourDataPtr(); //// 将IntPtr转换为C#的字符串 //string message = Marshal.PtrToStringAnsi(messagePtr); //OutlineDetector.DeletePointerArray(messagePtr); //if(!string.IsNullOrEmpty(message)) if(ptrPolygons != IntPtr.Zero) { //DrawerData.XyAddPolygonTree(this.pXy, ptrPolygons, $"Layer M 轮廓线\r\n{message}"); DrawerData.XyAddPolygonTree(this.pXy, ptrPolygons, $"轮廓线"); this.PushDataClick?.Invoke(sender, e); MessageBox.Show("轮廓线已成功回写!"); } } } }