792 lines
21 KiB
C#
792 lines
21 KiB
C#
using ACS.SPiiPlusNET;
|
|
using HexcalMC.Base;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.Drawing;
|
|
using System.Drawing.Imaging;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Windows.Forms;
|
|
using Telerik.WinControls.UI;
|
|
using cColorScheme = Plot3D.Editor3D.cColorScheme;
|
|
using cLine3D = Plot3D.Editor3D.cLine3D;
|
|
using cLineData = Plot3D.Editor3D.cLineData;
|
|
using cMessgData = Plot3D.Editor3D.cMessgData;
|
|
|
|
// classes
|
|
using cObject3D = Plot3D.Editor3D.cObject3D;
|
|
using cPoint3D = Plot3D.Editor3D.cPoint3D;
|
|
using cScatterData = Plot3D.Editor3D.cScatterData;
|
|
using cShape3D = Plot3D.Editor3D.cShape3D;
|
|
|
|
// callback function
|
|
using eColorScheme = Plot3D.Editor3D.eColorScheme;
|
|
using eInvalidate = Plot3D.Editor3D.eInvalidate;
|
|
using eMouseCtrl = Plot3D.Editor3D.eMouseCtrl;
|
|
using eNormalize = Plot3D.Editor3D.eNormalize;
|
|
|
|
// enums
|
|
using eRaster = Plot3D.Editor3D.eRaster;
|
|
using eScatterShape = Plot3D.Editor3D.eScatterShape;
|
|
using eSelEvent = Plot3D.Editor3D.eSelEvent;
|
|
using eSelType = Plot3D.Editor3D.eSelType;
|
|
|
|
namespace HexcalMC
|
|
{
|
|
internal enum eDemo
|
|
{
|
|
Math_Callback,
|
|
Math_Formula,
|
|
Surface_Fill,
|
|
Surface_Grid,
|
|
Surface_Fill_Missing,
|
|
Surface_Grid_Missing,
|
|
Nested_Graphs,
|
|
Scatter_Plot,
|
|
Connected_Lines,
|
|
Scatter_Shapes,
|
|
Pyramid,
|
|
Sphere_Fill_Closed,
|
|
Sphere_Fill_Open,
|
|
Sphere_Grid,
|
|
Valentine,
|
|
Animation,
|
|
}
|
|
|
|
public partial class EtalonForm : System.Windows.Forms.Form
|
|
{
|
|
private eDemo me_Demo;
|
|
private eColorScheme me_ColorScheme;
|
|
private System.Windows.Forms.Timer mi_StatusTimer = new System.Windows.Forms.Timer();
|
|
private cMessgData mi_MesgTop = new cMessgData("", -7, 7, System.Drawing.Color.Blue); // For special hint
|
|
private cMessgData mi_MesgBottom = new cMessgData("", -7, -7, System.Drawing.Color.Gray); // For selection mode
|
|
|
|
// Only for demo "Animation"
|
|
private System.Windows.Forms.Timer mi_AnimationTimer = new System.Windows.Forms.Timer();
|
|
|
|
private cScatterData mi_SinusData;
|
|
private cPoint3D[] mi_Pyramid;
|
|
private int ms32_AnimationAngle;
|
|
|
|
// etalon解析变量
|
|
private List<Point> etalon_points = new List<Point>();
|
|
|
|
private List<Point> filteredPoints = new List<Point>(); //过滤后的点
|
|
private List<int> dwellTimes = new List<int>();
|
|
|
|
private static System.Windows.Forms.Timer refresh_time = new System.Windows.Forms.Timer();
|
|
private static int currentIndex = 0;
|
|
|
|
private readonly MainForm mainFrom;
|
|
private readonly Api _acs; //ACS控制器
|
|
private double dwellTime = 2000; //停顿时间
|
|
|
|
public Axis[] axes =
|
|
{
|
|
Axis.ACSC_AXIS_0,
|
|
Axis.ACSC_AXIS_1,
|
|
Axis.ACSC_AXIS_8,
|
|
Axis.ACSC_NONE,
|
|
}; //使能的轴
|
|
|
|
public class Point
|
|
{
|
|
public double X { get; }
|
|
public double Y { get; }
|
|
public double Z { get; }
|
|
|
|
public Point(double x, double y, double z)
|
|
{
|
|
X = x;
|
|
Y = y;
|
|
Z = z;
|
|
}
|
|
|
|
// 从 Point 转换
|
|
public static Point3D FromPoint(Point point)
|
|
{
|
|
return new Point3D(point.X, point.Y, point.Z);
|
|
}
|
|
}
|
|
|
|
public EtalonForm(MainForm _mainFrom)
|
|
{
|
|
InitializeComponent();
|
|
mainFrom = _mainFrom;
|
|
this._acs = _mainFrom._acs;
|
|
}
|
|
|
|
private void EtalonForm_Load(object sender, EventArgs e)
|
|
{
|
|
InitScatterPlot(); //清空绘图
|
|
|
|
DebugDfn.textBox_Msg = this.text_etalon_info;
|
|
}
|
|
|
|
#region 绘图区功能
|
|
|
|
private void InitScatterPlot() //绘图区初始化
|
|
{
|
|
comboColors.Sorted = false;
|
|
foreach (eColorScheme e_Scheme in Enum.GetValues(typeof(eColorScheme)))
|
|
{
|
|
comboColors.Items.Add(e_Scheme.ToString().Replace('_', ' '));
|
|
}
|
|
comboColors.SelectedIndex = (int)eColorScheme.Monochrome; //默认色卡
|
|
|
|
comboRaster.Sorted = false;
|
|
foreach (eRaster e_Raster in Enum.GetValues(typeof(eRaster)))
|
|
{
|
|
comboRaster.Items.Add(e_Raster);
|
|
}
|
|
comboRaster.SelectedIndex = (int)eRaster.Labels; //坐标系栅格样式
|
|
|
|
//设置默认
|
|
comboMouse.SelectedIndex = 0;
|
|
|
|
// 设置定时器
|
|
refresh_time.Interval = 100;
|
|
refresh_time.Tick += new EventHandler(OnAnimationTimer);
|
|
refresh_time.Start();
|
|
}
|
|
|
|
private void DemoScatterPlot(bool b_Lines)
|
|
{
|
|
comboColors.Enabled = true; // Some of the demos will disable this combobox
|
|
me_ColorScheme = (eColorScheme)comboColors.SelectedIndex;
|
|
|
|
checkMirrorX.Checked = editor3D.AxisX.Mirror;
|
|
checkMirrorY.Checked = editor3D.AxisY.Mirror;
|
|
|
|
// 3 pixels for line width and for circle radius
|
|
const int SIZE = 3;
|
|
|
|
cColorScheme i_Scheme = new cColorScheme(me_ColorScheme);
|
|
cScatterData i_ShapeData = new cScatterData(i_Scheme);
|
|
cLineData i_LineData = new cLineData(i_Scheme);
|
|
List<cPoint3D> i_Points = new List<cPoint3D>();
|
|
|
|
for (double P = -22.0; P < 22.0; P += 0.1)
|
|
{
|
|
double d_X = Math.Sin(P) * P;
|
|
double d_Y = Math.Cos(P) * P;
|
|
double d_Z = P;
|
|
if (d_Z > 0.0)
|
|
d_Z /= 3.0;
|
|
|
|
cPoint3D i_Point = new cPoint3D(d_X, d_Y, d_Z, "Scatter Point");
|
|
if (b_Lines)
|
|
{
|
|
i_Points.Add(i_Point);
|
|
}
|
|
else // Shapes
|
|
{
|
|
// You can store the returned shape in a variable and later modify it's properties
|
|
cShape3D i_Shape = i_ShapeData.AddShape(
|
|
i_Point,
|
|
eScatterShape.Circle,
|
|
SIZE,
|
|
null
|
|
);
|
|
}
|
|
}
|
|
|
|
// You can store the returned lines in a variable and later modify their properties
|
|
cLine3D[] i_Lines = i_LineData.AddConnectedLines(i_Points, SIZE, null);
|
|
|
|
// Depending on your use case you can also specify MaintainXY or MaintainXYZ here
|
|
editor3D.Clear();
|
|
editor3D.Normalize = eNormalize.Separate;
|
|
editor3D.AddRenderData(i_ShapeData, i_LineData);
|
|
|
|
editor3D.Selection.HighlightColor = System.Drawing.Color.FromArgb(90, 90, 90);
|
|
editor3D.Selection.Callback = OnSelectEvent;
|
|
editor3D.Selection.MultiSelect = true;
|
|
editor3D.Selection.Enabled = true;
|
|
editor3D.UndoBuffer.Enabled = true;
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private eInvalidate OnSelectEvent(
|
|
eSelEvent e_Event,
|
|
Keys e_Modifiers,
|
|
int s32_DeltaX,
|
|
int s32_DeltaY,
|
|
cObject3D i_Object
|
|
) //
|
|
{
|
|
eInvalidate e_Invalidate = eInvalidate.NoChange;
|
|
|
|
bool b_CTRL = (e_Modifiers & Keys.Control) > 0;
|
|
|
|
// The left mouse button went down with ALT key down and CTRL key up
|
|
if (e_Event == eSelEvent.MouseDown && !b_CTRL && i_Object != null)
|
|
{
|
|
i_Object.Selected = !i_Object.Selected;
|
|
|
|
// After changing the selection status the object must be redrawn.
|
|
e_Invalidate = eInvalidate.Invalidate;
|
|
}
|
|
else if (e_Event == eSelEvent.MouseDrag && b_CTRL)
|
|
{
|
|
// The user is dragging the mouse with ALT + CTRL keys down. Convert the mouse
|
|
// movement in the 2D space into a movement in the 3D space.
|
|
cPoint3D i_Project = editor3D.ReverseProject(s32_DeltaX, s32_DeltaY);
|
|
|
|
// GetSelectedPoints() returns only unique points.
|
|
cPoint3D[] i_Selected = editor3D.Selection.GetSelectedPoints(eSelType.All);
|
|
foreach (cPoint3D i_Point in i_Selected)
|
|
{
|
|
switch (me_Demo)
|
|
{
|
|
case eDemo.Pyramid:
|
|
case eDemo.Scatter_Shapes:
|
|
case eDemo.Scatter_Plot:
|
|
case eDemo.Connected_Lines:
|
|
// The pyramid line end points / scatter shapes can be moved freely in
|
|
// the 3D space
|
|
i_Point.Move(i_Project.X, i_Project.Y, i_Project.Z);
|
|
break;
|
|
|
|
case eDemo.Surface_Fill:
|
|
case eDemo.Surface_Grid:
|
|
case eDemo.Surface_Fill_Missing:
|
|
case eDemo.Surface_Grid_Missing:
|
|
// The points in the Surface grid have a fixed X,Y position, only Z can
|
|
// be modified.
|
|
i_Point.Move(0, 0, i_Project.Z);
|
|
break;
|
|
|
|
default:
|
|
Debug.Assert(false);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Set flag to recalculate the coordinate system, then Invalidate()
|
|
e_Invalidate = eInvalidate.CoordSystem;
|
|
}
|
|
|
|
mi_StatusTimer.Stop();
|
|
|
|
mi_StatusTimer.Start();
|
|
return e_Invalidate;
|
|
}
|
|
|
|
private void comboRaster_SelectedIndexChanged(object sender, EventArgs e) //坐标栅格样式
|
|
{
|
|
editor3D.Raster = (eRaster)comboRaster.SelectedIndex;
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private void checkMirrorY_CheckedChanged(object sender, EventArgs e) //Y轴镜像
|
|
{
|
|
editor3D.AxisY.Mirror = checkMirrorY.Checked;
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private void checkMirrorX_CheckedChanged(object sender, EventArgs e) //x轴镜像
|
|
{
|
|
editor3D.AxisX.Mirror = checkMirrorX.Checked;
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private void btnReset_Click(object sender, EventArgs e) //重置视图
|
|
{
|
|
editor3D.SetCoefficients(1350, 70, 230);
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private void btnScreenshot_Click(object sender, EventArgs e) //截图保存
|
|
{
|
|
SaveFileDialog i_Dlg = new SaveFileDialog();
|
|
i_Dlg.Title = "Save as PNG image";
|
|
i_Dlg.Filter = "PNG Image|*.png";
|
|
i_Dlg.DefaultExt = ".png";
|
|
|
|
if (DialogResult.Cancel == i_Dlg.ShowDialog(this))
|
|
return;
|
|
|
|
Bitmap i_Bitmap = editor3D.GetScreenshot();
|
|
try
|
|
{
|
|
i_Bitmap.Save(i_Dlg.FileName, ImageFormat.Png);
|
|
}
|
|
catch (Exception Ex)
|
|
{
|
|
MessageBox.Show(
|
|
this,
|
|
Ex.Message,
|
|
"Error",
|
|
MessageBoxButtons.OK,
|
|
MessageBoxIcon.Error
|
|
);
|
|
}
|
|
}
|
|
|
|
private void comboMouse_SelectedIndexChanged(object sender, EventArgs e) //鼠标控制方式
|
|
{
|
|
switch (comboMouse.SelectedIndex)
|
|
{
|
|
case 0:
|
|
editor3D.SetUserInputs(eMouseCtrl.L_Theta_R_Phi);
|
|
labelMouseInfo.Text = "鼠标左键:升高,鼠标右键:旋转";
|
|
break;
|
|
|
|
case 1:
|
|
editor3D.SetUserInputs(eMouseCtrl.L_Theta_L_Phi);
|
|
labelMouseInfo.Text = "鼠标左键:升高和旋转";
|
|
break;
|
|
|
|
case 2:
|
|
editor3D.SetUserInputs(eMouseCtrl.M_Theta_M_Phi);
|
|
labelMouseInfo.Text = "鼠标中键:升高和旋转";
|
|
break;
|
|
|
|
default:
|
|
Debug.Assert(false);
|
|
break;
|
|
}
|
|
|
|
labelMouseInfo.Text +=
|
|
", 鼠标左键 + SHIFT:移动、鼠标左键 + CTRL 或滚轮:缩放、鼠标左键 + ALT:选择";
|
|
}
|
|
|
|
private void comboColors_SelectedIndexChanged(object sender, EventArgs e)
|
|
{
|
|
me_ColorScheme = (eColorScheme)comboColors.SelectedIndex;
|
|
|
|
//判断 points 是否为空,表示当前是否已经有真实数据
|
|
if (etalon_points.Count > 0)
|
|
{
|
|
PointScatterPlot(etalon_points); //更新真实数据
|
|
}
|
|
//else
|
|
//{
|
|
// DemoScatterPlot(false); //更新虚拟数据
|
|
//}
|
|
}
|
|
|
|
#endregion 绘图区功能
|
|
|
|
#region etalon文件解析
|
|
|
|
private void moveToPoint()
|
|
{
|
|
DebugDfn.AddLogText("添加到运动队列");
|
|
int timeout = 5000;
|
|
|
|
//判断电机状态
|
|
if (!mainFrom.totalAxisEnabled)
|
|
{
|
|
DebugDfn.AddLogText("存在电机未使能");
|
|
|
|
_acs.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); //Y轴
|
|
// Wait axis 1 enabled during 5 sec
|
|
_acs.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout);
|
|
|
|
_acs.WaitMotorEnabled(Axis.ACSC_AXIS_8, 1, timeout);
|
|
|
|
//DebugDfn.AddLogText("电机已启用");
|
|
}
|
|
|
|
// 创建多点运动
|
|
dwellTime = dwellTimes.Average() * 1000; //将秒转换为毫秒
|
|
DebugDfn.AddLogText("平均停顿时间(毫秒):" + dwellTime);
|
|
_acs.MultiPointM(MotionFlags.ACSC_NONE, axes, dwellTime);
|
|
|
|
//判断是否有点
|
|
if (filteredPoints.Count == 0)
|
|
{
|
|
DebugDfn.AddLogText("没有点");
|
|
return;
|
|
}
|
|
//打印点的数量
|
|
DebugDfn.AddLogText("待添加点的数量:" + filteredPoints.Count);
|
|
// 添加符合条件的点到运动路径中
|
|
foreach (var point in filteredPoints)
|
|
{
|
|
double[] points = new double[3];
|
|
points[0] = point.Y;
|
|
points[1] = point.X;
|
|
points[2] = point.Z;
|
|
_acs.AddPointM(axes, points);
|
|
//打印添加的点
|
|
DebugDfn.AddLogText("添加点:" + points[0] + " " + points[1] + " " + points[2]);
|
|
}
|
|
// 打印添加点的数量
|
|
DebugDfn.AddLogText("已添加点的数量:" + filteredPoints.Count);
|
|
|
|
// Finish the motion End of the multi-point motion
|
|
_acs.EndSequenceM(axes);
|
|
|
|
mainFrom.StopCounting();
|
|
//启动统计
|
|
mainFrom.StartCounting();
|
|
}
|
|
|
|
private void btn_startmove_Click(object sender, EventArgs e) //开始运动
|
|
{
|
|
int timeout = 5000;
|
|
//判断电机状态
|
|
if (!mainFrom.totalAxisEnabled)
|
|
{
|
|
DebugDfn.AddLogText("存在电机未使能");
|
|
|
|
_acs.WaitMotorEnabled(Axis.ACSC_AXIS_0, 1, timeout); //Y轴
|
|
// Wait axis 1 enabled during 5 sec
|
|
_acs.WaitMotorEnabled(Axis.ACSC_AXIS_1, 1, timeout);
|
|
|
|
_acs.WaitMotorEnabled(Axis.ACSC_AXIS_8, 1, timeout);
|
|
|
|
//DebugDfn.AddLogText("电机已启用");
|
|
}
|
|
|
|
//判断是否有点
|
|
if (filteredPoints.Count == 0)
|
|
{
|
|
MessageBox.Show("没有需要移动的点,请先导入", "ERROR");
|
|
return;
|
|
}
|
|
//打印点的数量
|
|
DebugDfn.AddLogText("待添加点的数量:" + filteredPoints.Count);
|
|
|
|
//启动运动定时器
|
|
timer_move.Start();
|
|
refresh_time.Start();
|
|
}
|
|
|
|
private void btn_stop_Click(object sender, EventArgs e) //停止运动
|
|
{
|
|
DebugDfn.AddLogText("停止运动");
|
|
try
|
|
{
|
|
Axis[] m_arrAxisList = new Axis[]
|
|
{
|
|
Axis.ACSC_AXIS_0,
|
|
Axis.ACSC_AXIS_1,
|
|
Axis.ACSC_AXIS_8,
|
|
Axis.ACSC_NONE,
|
|
};
|
|
|
|
if (m_arrAxisList != null)
|
|
_acs.HaltM(m_arrAxisList);
|
|
|
|
DebugDfn.AddLogText("立即停止 已发送命令");
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show(ex.Message, "ERROR", MessageBoxButtons.OK, MessageBoxIcon.Error);
|
|
Debug.WriteLine(ex.Message);
|
|
}
|
|
|
|
//停止统计
|
|
mainFrom.StopCounting();
|
|
refresh_time.Stop();
|
|
timer_move.Stop();
|
|
currentIndex = 0;
|
|
}
|
|
|
|
private void btn_etalon_import_Click(object sender, EventArgs e) //解析Etalon文件
|
|
{
|
|
//打开文件对号框,选择 mpf格式文件
|
|
OpenFileDialog i_Dlg = new OpenFileDialog();
|
|
i_Dlg.Title = "导入Etalon文件";
|
|
i_Dlg.Filter = "Etalon文件|*.mpf";
|
|
i_Dlg.DefaultExt = ".mpf";
|
|
i_Dlg.Multiselect = false;
|
|
|
|
if (DialogResult.Cancel == i_Dlg.ShowDialog(this))
|
|
return;
|
|
|
|
//读取文件
|
|
string s_File = i_Dlg.FileName;
|
|
|
|
//设置路径显示
|
|
|
|
DebugDfn.AddLogText("导入Etalon文件:" + s_File);
|
|
|
|
//解析文件
|
|
parse_mpf_file(s_File);
|
|
|
|
DebugDfn.AddLogText("Etalon文件解析完成");
|
|
}
|
|
|
|
private bool parse_mpf_file(string mpf_file_path) // 编写解析mpf文件的函数
|
|
{
|
|
//; Machine: ZIM
|
|
//; Position: 1
|
|
//; Created: 2/15/2023 12:29:13 PM
|
|
//; Program: TRAC-CAL V48, Build: 10, 5/13/2022 8:29:25 AM
|
|
//; File: 'cncData.xml'
|
|
//G71
|
|
//G90
|
|
//G500
|
|
//G01 X8000.000 Y200.000 Z-1400.000 F2000 //坐标
|
|
//G04 F=2 // 停顿时间
|
|
//G01 X7800.000 Y300.000 Z-1400.000 F2000
|
|
//G04 F=2
|
|
//G01 X7600.000 Y400.000 Z-1400.000 F2000
|
|
//G04 F=2
|
|
//G01 X7400.000 Y500.000 Z-1400.000 F2000
|
|
//G04 F=2
|
|
//G01 X7200.000 Y600.000 Z-1400.000 F2000
|
|
|
|
//判断文件是否存在
|
|
if (!File.Exists(mpf_file_path))
|
|
{
|
|
MessageBox.Show("文件不存在");
|
|
return false;
|
|
}
|
|
|
|
//清空之前的数据
|
|
etalon_points.Clear();
|
|
filteredPoints.Clear();
|
|
dwellTimes.Clear();
|
|
currentIndex = 0; //重置当前点
|
|
|
|
//读取文件
|
|
string[] lines = File.ReadAllLines(mpf_file_path);
|
|
Regex regex = new Regex(
|
|
@"G01 X(?<X>[-+]?\d*\.?\d+) Y(?<Y>[-+]?\d*\.?\d+) Z(?<Z>[-+]?\d*\.?\d+)"
|
|
);
|
|
Regex dwellRegex = new Regex(@"G04 F=(?<F>\d+)");
|
|
|
|
foreach (string line in lines)
|
|
{
|
|
Match match = regex.Match(line);
|
|
if (match.Success)
|
|
{
|
|
double x = double.Parse(match.Groups["X"].Value);
|
|
double y = double.Parse(match.Groups["Y"].Value);
|
|
double z = double.Parse(match.Groups["Z"].Value);
|
|
etalon_points.Add(new Point(x, y, z));
|
|
}
|
|
|
|
Match dwellMatch = dwellRegex.Match(line);
|
|
if (dwellMatch.Success)
|
|
{
|
|
int f = int.Parse(dwellMatch.Groups["F"].Value);
|
|
dwellTimes.Add(f);
|
|
}
|
|
}
|
|
|
|
// 输出解析结果
|
|
//Console.WriteLine("Points:");
|
|
//foreach (var point in etalon_points)
|
|
//{
|
|
// Console.WriteLine($"X: {point.X}, Y: {point.Y}, Z: {point.Z}");
|
|
//}
|
|
|
|
//Console.WriteLine("Dwell Times:");
|
|
//foreach (var dwellTime in dwellTimes)
|
|
//{
|
|
// Console.WriteLine($"F: {dwellTime}");
|
|
//}
|
|
|
|
//过滤点集
|
|
foreach (var point in etalon_points)
|
|
{
|
|
if (MainForm.IsWithinLimit(point)) //判断点是否在行程范围内
|
|
{
|
|
filteredPoints.Add(point);
|
|
}
|
|
}
|
|
|
|
//打印过滤后的点集大小
|
|
DebugDfn.AddLogText("过滤后的点集大小:" + filteredPoints.Count);
|
|
PointScatterPlot(filteredPoints); //绘制散点图
|
|
return true;
|
|
}
|
|
|
|
#endregion etalon文件解析
|
|
|
|
#region 3D绘图逻辑
|
|
|
|
private void PointScatterPlot(List<Point> points) //绘制散点图
|
|
{
|
|
//清空绘图
|
|
editor3D.Clear();
|
|
editor3D.Normalize = eNormalize.Separate;
|
|
editor3D.Invalidate();
|
|
|
|
//判断点集是否为空
|
|
comboColors.Enabled = true; // Some of the demos will disable this combobox
|
|
me_ColorScheme = (eColorScheme)comboColors.SelectedIndex;
|
|
|
|
checkMirrorX.Checked = editor3D.AxisX.Mirror;
|
|
checkMirrorY.Checked = editor3D.AxisY.Mirror;
|
|
|
|
// 3 pixels for line width and for circle radius
|
|
const int SIZE = 3;
|
|
|
|
cColorScheme i_Scheme = new cColorScheme(me_ColorScheme);
|
|
cScatterData i_ShapeData = new cScatterData(i_Scheme);
|
|
cLineData i_LineData = new cLineData(i_Scheme);
|
|
List<cPoint3D> i_Points = new List<cPoint3D>();
|
|
|
|
foreach (var point in points)
|
|
{
|
|
double d_X = point.X;
|
|
double d_Y = point.Y;
|
|
double d_Z = point.Z;
|
|
|
|
cPoint3D i_Point = new cPoint3D(d_X, d_Y, d_Z, "Scatter Point");
|
|
|
|
// You can store the returned shape in a variable and later modify it's properties
|
|
cShape3D i_Shape = i_ShapeData.AddShape(i_Point, eScatterShape.Circle, SIZE, null);
|
|
}
|
|
|
|
// You can store the returned lines in a variable and later modify their properties
|
|
cLine3D[] i_Lines = i_LineData.AddConnectedLines(i_Points, SIZE, null);
|
|
|
|
// Depending on your use case you can also specify MaintainXY or MaintainXYZ here
|
|
editor3D.Clear();
|
|
editor3D.Normalize = eNormalize.Separate;
|
|
editor3D.AddRenderData(i_ShapeData, i_LineData);
|
|
|
|
editor3D.Selection.HighlightColor = System.Drawing.Color.FromArgb(90, 90, 90);
|
|
editor3D.Selection.Callback = OnSelectEvent;
|
|
editor3D.Selection.MultiSelect = true;
|
|
editor3D.Selection.Enabled = true;
|
|
editor3D.UndoBuffer.Enabled = true;
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private void btn_clear_Click(object sender, EventArgs e) //清空绘图
|
|
{
|
|
editor3D.Clear();
|
|
editor3D.Normalize = eNormalize.Separate;
|
|
editor3D.Invalidate();
|
|
}
|
|
|
|
private void btn_draw_test_Click(object sender, EventArgs e)
|
|
{
|
|
DemoScatterPlot(false);
|
|
}
|
|
|
|
private void OnAnimationTimer(object sender, EventArgs e)
|
|
{
|
|
cScatterData i_ShapeData = new cScatterData();
|
|
//currentIndex = mainFrom.GetInPosCount();//获取当前点的数量
|
|
|
|
for (int i = 0; i < filteredPoints.Count; i++) //遍历所有点
|
|
{
|
|
if (i < currentIndex - 1) //小于的部分,已跑完 为绿色
|
|
{
|
|
double d_X = filteredPoints[i].X;
|
|
double d_Y = filteredPoints[i].Y;
|
|
double d_Z = filteredPoints[i].Z;
|
|
|
|
cPoint3D i_Point = new cPoint3D(d_X, d_Y, d_Z, "Scatter Point");
|
|
SolidBrush i_brush = new SolidBrush(System.Drawing.Color.Green);
|
|
// You can store the returned shape in a variable and later modify it's properties
|
|
cShape3D i_Shape = i_ShapeData.AddShape(
|
|
i_Point,
|
|
eScatterShape.Circle,
|
|
5,
|
|
i_brush,
|
|
null
|
|
);
|
|
}
|
|
else if (i == currentIndex - 1) //当前点为橙黄色
|
|
{
|
|
double d_X = filteredPoints[i].X;
|
|
double d_Y = filteredPoints[i].Y;
|
|
double d_Z = filteredPoints[i].Z;
|
|
|
|
cPoint3D i_Point = new cPoint3D(d_X, d_Y, d_Z, "Scatter Point");
|
|
SolidBrush i_brush = new SolidBrush(System.Drawing.Color.OrangeRed);
|
|
// You can store the returned shape in a variable and later modify it's properties
|
|
cShape3D i_Shape = i_ShapeData.AddShape(
|
|
i_Point,
|
|
eScatterShape.Circle,
|
|
5,
|
|
i_brush,
|
|
null
|
|
);
|
|
}
|
|
else
|
|
{
|
|
double d_X = filteredPoints[i].X;
|
|
double d_Y = filteredPoints[i].Y;
|
|
double d_Z = filteredPoints[i].Z;
|
|
|
|
cPoint3D i_Point = new cPoint3D(d_X, d_Y, d_Z, "Scatter Point");
|
|
SolidBrush i_brush = new SolidBrush(System.Drawing.Color.Gray);
|
|
// You can store the returned shape in a variable and later modify it's properties
|
|
cShape3D i_Shape = i_ShapeData.AddShape(
|
|
i_Point,
|
|
eScatterShape.Circle,
|
|
3,
|
|
i_brush,
|
|
null
|
|
);
|
|
}
|
|
|
|
editor3D.Clear();
|
|
editor3D.Normalize = eNormalize.Separate;
|
|
editor3D.AddRenderData(i_ShapeData);
|
|
editor3D.Invalidate();
|
|
}
|
|
}
|
|
|
|
#endregion 3D绘图逻辑
|
|
|
|
#region 队列移动逻辑
|
|
|
|
private void timer_move_Tick(object sender, EventArgs e)
|
|
{
|
|
// 检查是否到达目标点
|
|
if (IsAtTarget())
|
|
{
|
|
// 移动到下一个点
|
|
MoveToNextPoint();
|
|
}
|
|
}
|
|
|
|
private void MoveToNextPoint()
|
|
{
|
|
if (filteredPoints.Count > 0 && currentIndex < filteredPoints.Count)
|
|
{
|
|
//增加2秒延时
|
|
Thread.Sleep((int)dwellTime);
|
|
//int currentDwellTime = dwellTimes[currentIndex] * 1000; // 将秒转换为毫秒
|
|
//Thread.Sleep(currentDwellTime);
|
|
|
|
Point nextPoint = filteredPoints[currentIndex];
|
|
//打印 nextPoint
|
|
DebugDfn.AddLogText(
|
|
"下发指令:"
|
|
+ currentIndex
|
|
+ " 点:"
|
|
+ nextPoint.X
|
|
+ " "
|
|
+ nextPoint.Y
|
|
+ " "
|
|
+ nextPoint.Z
|
|
);
|
|
currentIndex++;
|
|
mainFrom.SetPositionXyz(Point.FromPoint(nextPoint)); //移动到下一个点
|
|
}
|
|
else
|
|
{
|
|
DebugDfn.AddLogText("All points have been visited.");
|
|
timer_move.Stop();
|
|
currentIndex = 0;
|
|
}
|
|
}
|
|
|
|
private bool IsAtTarget()
|
|
{
|
|
// 这里你需要实现实际的到位判断逻辑 例如,通过读取传感器数据或运动控制器的状态 这里假设总是返回 true 作为示例
|
|
|
|
return mainFrom.GetIsMoving();
|
|
}
|
|
|
|
#endregion 队列移动逻辑
|
|
}
|
|
} |