2026-03-30 17:09:29 +09:00

589 lines
18 KiB
C#

using CoreUnit.Common;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Text.Json;
using System.Windows.Forms;
using System.Xml;
namespace CoreUnit.Control.UserControl.Canvas
{
public class Spline : DrawObjectBase, IDrawObject, ISerialize
{
//토네이도 중심
protected UnitPoint m_center;
[Browsable(false)]
public UnitPoint Center {
get { return m_center; }
set { m_center = value; }
}
//Spline의 경우 PointList 1개
protected List<UnitPoint> m_p1 = new List<UnitPoint>();
[Browsable(false)]
public List<UnitPoint> P1 {
get { return m_p1; }
set { m_p1 = value; }
}
//Tornado의 경우 PointList 2개
protected List<UnitPoint> m_p2 = new List<UnitPoint>();
[Browsable(false)]
public List<UnitPoint> P2 {
get { return m_p2; }
set { m_p2 = value; }
}
protected double m_wholeLength = 10;
[Browsable(true)]
public double WholeLength {
get { return m_wholeLength; }
set { m_wholeLength = value; }
}
protected float m_startAngle = 0;
protected float m_radius = 5;
protected double m_innerRadius = 0.2;
protected double m_increaseFactor = 0.00694;
public static string ObjectType {
get { return "Spline"; }
}
protected bool m_splineDirection = false;
protected bool m_splineTornado = true;
protected DrawWayType m_drawWay = DrawWayType.OUT_OUT;
public enum DrawWayType
{
OUT_OUT,
IN_OUT,
OUT_IN,
IN_IN
}
public Spline()
{
}
public Spline(UnitPoint center, float width, Color color)
{
Center = center;
Width = width;
Color = color;
Selected = false;
}
public override void InitializeFromModel(UnitPoint center, DrawingLayer layer, ISnapPoint snap)
{
Center = center;
Width = layer.Width;
Color = layer.Color;
Selected = true;
}
static int ThresholdPixel = 6;
static float ThresholdWidth(ICanvas canvas, float objectwidth)
{
return ThresholdWidth(canvas, objectwidth, ThresholdPixel);
}
public static float ThresholdWidth(ICanvas canvas, float objectwidth, float pixelwidth)
{
double minWidth = canvas.ToUnit(pixelwidth);
double width = Math.Max(objectwidth / 2, minWidth);
return (float)width;
}
public virtual void Copy(Spline acopy)
{
base.Copy(acopy);
P1 = acopy.P1;
P2 = acopy.P2;
Center = acopy.Center;
m_startAngle = acopy.m_startAngle;
m_radius = acopy.m_radius;
m_innerRadius = acopy.m_innerRadius;
m_increaseFactor = acopy.m_increaseFactor;
m_splineDirection = acopy.m_splineDirection;
m_splineTornado = acopy.m_splineTornado;
Type = acopy.Type;
m_no = acopy.m_no;
m_drawWay = acopy.m_drawWay;
//마킹객체에 대한 속성 복사
ScannerParamNo = acopy.ScannerParamNo;
Enabled = acopy.Enabled;
Selected = acopy.Selected;
WeldingParameterID = acopy.WeldingParameterID;
}
public RectangleF GetBoundingRect(ICanvas canvas)
{
float thWidth = ThresholdWidth(canvas, m_radius);
UnitPoint newPoint1 = new UnitPoint(m_center.X - thWidth / 2, m_center.Y - thWidth / 2);
UnitPoint newPoint2 = new UnitPoint(m_center.X + thWidth / 2, m_center.Y + thWidth / 2);
return ScreenUtils.GetRect(newPoint1, newPoint2, thWidth);
}
#region IDrawObject Members
public virtual IDrawObject Clone()
{
Spline l = new Spline();
l.Copy(this);
return l;
}
#region IObjectEditInstance
public IDrawObject GetDrawObject()
{
return new Spline(Center, Width, Color);
}
#endregion
public bool PointInObject(ICanvas canvas, UnitPoint point)
{
RectangleF boundingrect = GetBoundingRect(canvas);
if (boundingrect.Contains(point.Point) == false)
return false;
float thWidth = Line.ThresholdWidth(canvas, Width, ThresholdPixel);
if (HitUtil.PointInPoint(m_center, point, m_radius))
return true;
return HitUtil.IsPointInCircle(m_center, m_radius, point, thWidth / 2);
}
public bool ObjectInRectangle(ICanvas canvas, RectangleF rect, bool anyPoint)
{
RectangleF boundingrect = GetBoundingRect(canvas);
UnitPoint newPoint1 = new UnitPoint(boundingrect.X, boundingrect.Y);
UnitPoint newPoint2 = new UnitPoint(boundingrect.X + boundingrect.Width, boundingrect.Y + boundingrect.Height);
if (anyPoint)
return HitUtil.LineIntersectWithRect(newPoint1, newPoint2, rect);
return rect.Contains(boundingrect);
}
#region 마킹객체에 대한 속성
bool m_enabled = true;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Enable Mark", 6, 6)]
[Description("Enable Mark")]
[XmlSerializable]
public bool Enabled {
get { return m_enabled; }
set { m_enabled = value; }
}
int m_scannerParamNo = 0;
[Browsable(false)]
[ReadOnly(false)]
[Category("용접 파라미터")]
[DisplayName("용접 조건 번호")]
[Description("용접 조건(스캔속도 및 레이저 파워 값등..) 번호 설정")]
[XmlSerializable]
public int ScannerParamNo {
get { return m_scannerParamNo; }
set { m_scannerParamNo = value; }
}
[Browsable(false)]
[ReadOnly(false)]
[Category("용접 파라미터")]
[DisplayName("용접 조건 ID")]
[Description("용접 조건(스캔속도 및 레이저 파워 값등..) ID 설정")]
[XmlSerializable]
public int ScannerParamID {
get { return m_scannerParamNo + 1; }
set { m_scannerParamNo = value - 1; }
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Pen", 2, 6)]
[CustomSortedDisplayName("Parameter", 1, 1)]
[Description("Welding Paramter ID")]
[Editor(typeof(WeldingParameterIDEditor.WeldingParamterNoUITypeEditor), typeof(System.Drawing.Design.UITypeEditor))]
[XmlSerializable]
public WeldingParameterIDEditor.eWeldingParamterID WeldingParameterID {
get { return (WeldingParameterIDEditor.eWeldingParamterID)ScannerParamID; }
set { ScannerParamID = (int)value; }
}
#endregion
#region 드로잉 객체에 대한 속성
int m_no;
[Browsable(false)]
[XmlSerializable]
public int No {
get { return m_no; }
set { m_no = value; }
}
string m_type;
[Browsable(false)]
[ReadOnly(true)]
[Category("객체")]
[DisplayName("종류")]
[Description("드로잉 객체 종류")]
[XmlSerializable]
public string Type {
get {
m_type = Spline.ObjectType;
return m_type;
}
set { m_type = value; }
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Center", 1, 6)]
[Description("Starting Point Of Drawing Object")]
[TypeConverter(typeof(PointFConverter))]
[XmlSerializable]
public PointF PF1 {
get { lock (this) { return Center.Point; } }
set { lock (this) { Center = new UnitPoint(value); } }
}
[Browsable(false)]
[ReadOnly(false)]
[Category("GEOMETRY")]
[DisplayName("2.End[X,Y](mm)")]
[Description("Starting Point Of Drawing Object")]
[TypeConverter(typeof(PointFConverter))]
[XmlSerializable]
public PointF PF2 {
get { lock (this) { return Center.Point; } }
set { lock (this) { Center = new UnitPoint(value); } }
}
[Browsable(false)]
[ReadOnly(false)]
[Category("GEOMETRY")]
[DisplayName("3.중심점[X,Y](mm)")]
[Description("드로잉 객체의 중심점")]
[TypeConverter(typeof(PointFConverter))]
public PointF MiddlePoint {
get { return Center.Point; }
set { Center = new UnitPoint(value); }
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Spiral Parameter", 4, 6)]
[CustomSortedDisplayName("Start Angle[˚]", 3, 6)]
[Description("Spline Start Angle(˚)")]
[XmlSerializable]
public float Angle {
get { return m_startAngle; }
set {
m_startAngle = value;
CreateSplinePointList();
}
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Radius[mm]", 2, 6)]
[Description("Spline Outer Radius(mm)")]
[XmlSerializable]
public float Radius {
get { return m_radius; }
set {
m_radius = value;
CreateSplinePointList();
}
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Inner Radius", 3, 6)]
[Description("Spline Inner Radius(mm)")]
[XmlSerializable]
public double InnerRadius {
get { return m_innerRadius; }
set {
m_innerRadius = value;
CreateSplinePointList();
}
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Reverse", 4, 6)]
[Description("Spline Direction")]
[XmlSerializable]
public bool SplineDirection {
get { return m_splineDirection; }
set {
m_splineDirection = value;
CreateSplinePointList();
}
}
bool m_lock = false;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Geometry", 3, 6)]
[CustomSortedDisplayName("Lock", 5, 6)]
[Description("Lock")]
[XmlSerializable]
public bool Lock {
get { return m_lock; }
set { m_lock = value; }
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Spiral Parameter", 4, 6)]
[CustomSortedDisplayName("Increase Factor[mm]", 1, 6)]
[Description("Spline Increase Factor(mm)")]
[XmlSerializable]
public double IncreaseFactor {
get { return m_increaseFactor; }
set {
m_increaseFactor = value;
CreateSplinePointList();
}
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Spiral Parameter", 4, 6)]
[CustomSortedDisplayName("Tornado Mode", 5, 6)]
[Description("Tornado Mode (True : Use, False : No Use)")]
[XmlSerializable]
public bool SplineTornado {
get { return m_splineTornado; }
set {
m_splineTornado = value;
CreateSplinePointList();
}
}
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Spiral Parameter", 4, 6)]
[CustomSortedDisplayName("Draw Way", 4, 6)]
[Description("Draw Way (OUT_OUT,IN_OUT, OUT_IN, IN_IN)")]
[XmlSerializable]
public DrawWayType DrawWay {
get { return m_drawWay; }
set {
m_drawWay = value;
}
}
public enum eAlignType { XY_ANGLE, XY_OFFSET, X_OFFSET, Y_OFFSET, ABSOLUTE_XY }
eAlignType m_alignType = eAlignType.ABSOLUTE_XY;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Vision Align", 5, 6)]
[CustomSortedDisplayName("Align Type", 1, 2)]
[Description("Align Type")]
[XmlSerializable]
public eAlignType AlignType {
get { return m_alignType; }
set { m_alignType = value; }
}
int m_alignID = -1;
[Browsable(true)]
[ReadOnly(false)]
[CustomSortedCategory("Vision Align", 5, 6)]
[CustomSortedDisplayName("Align ID", 2, 2)]
[Description("Align ID")]
[XmlSerializable]
public int AlignID {
get { return m_alignID; }
set { m_alignID = value; }
}
[Browsable(true)]
[ReadOnly(true)]
[CustomSortedCategory("Boundary", 1, 6)]
[CustomSortedDisplayName("Left,Bottom,Right,Top", 1, 1)]
[Description("Boundary of Object")]
[TypeConverter(typeof(RectangleFConverter))]
public RectangleF ClientRect {
get;
}
public void Move(UnitPoint offset)
{
m_center.X += offset.X;
m_center.Y += offset.Y;
}
public void Rotate(float angle, UnitPoint center)
{
Angle = Angle + angle;
}
public void MakeLength(float distance)
{
}
#endregion
public virtual void Draw(ICanvas canvas, RectangleF unitrect)
{
Color color = Color;
color = WeldingParameterIDEditor.weldingColorList[(int)WeldingParameterID - 1];
Pen pen = canvas.CreatePen(color, Width);
pen.EndCap = System.Drawing.Drawing2D.LineCap.Round;
pen.StartCap = System.Drawing.Drawing2D.LineCap.Round;
//PointList 생성
CreateSplinePointList();
if (Selected) {
DrawSpline(canvas, DrawUtils.SelectedPen);
} else {
//Spline 그리기
DrawSpline(canvas, pen);
}
}
private void CreateSplinePointList()
{
double distance = 0;
int index = 0;
m_p1.Clear();
m_p2.Clear();
while (true) {
UnitPoint p1 = new UnitPoint();
UnitPoint p2 = new UnitPoint();
double radianAngle = (m_startAngle + index * 2.5) * Math.PI / 180;
p1.X = (m_innerRadius + index * m_increaseFactor) * Math.Cos(radianAngle);
p1.Y = (m_innerRadius + index * m_increaseFactor) * Math.Sin(radianAngle);
p2.X = (-1) * p1.X;
p2.Y = (-1) * p1.Y;
//Reverse 인 경우 대칭
if (m_splineDirection == true) {
radianAngle = radianAngle * (-1);
p1.X = p1.X * (-1);
//p1.Y = p1.Y * (-1);
p2.X = p2.X * (-1);
//p2.Y = p2.Y * (-1);
}
distance = Math.Sqrt(Math.Pow(p1.X, 2) + Math.Pow(p1.Y, 2));
if (distance < m_radius) {
m_p1.Add(new UnitPoint(p1.X + Center.X, p1.Y + Center.Y));
m_p2.Add(new UnitPoint(p2.X + Center.X, p2.Y + Center.Y));
index++;
} else {
break;
}
}
m_wholeLength = 0;
for (int i = 0; i < m_p1.Count - 1; i++) {
m_wholeLength += HitUtil.Distance(m_p1[i], m_p1[i + 1]);
}
for (int i = 0; i < m_p2.Count - 1; i++) {
m_wholeLength += HitUtil.Distance(m_p2[i], m_p2[i + 1]);
}
}
private void DrawSpline(ICanvas canvas, Pen pen)
{
//일반 Spline 은 P1만 그림
for (int i = 0; i < m_p1.Count - 1; i++) {
canvas.DrawLine(canvas, pen, m_p1[i], m_p1[i + 1]);
}
// Tornado의 경우 P2까지 그려줌
if (m_splineTornado) {
for (int i = 0; i < m_p1.Count - 1; i++) {
canvas.DrawLine(canvas, pen, m_p2[i], m_p2[i + 1]);
}
}
}
public virtual void OnMouseMove(ICanvas canvas, UnitPoint point)
{
}
public virtual eDrawObjectMouseDown OnMouseDown(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
{
Selected = false;
m_center = point;
return eDrawObjectMouseDown.Done;
}
public void OnMouseUp(ICanvas canvas, UnitPoint point, ISnapPoint snappoint)
{
}
public virtual void OnKeyDown(ICanvas canvas, KeyEventArgs e)
{
}
[Browsable(false)]
public UnitPoint RepeatStartingPoint {
get { return m_center; }
}
public INodePoint NodePoint(ICanvas canvas, UnitPoint point)
{
return null;
}
public ISnapPoint SnapPoint(ICanvas canvas, UnitPoint point, List<IDrawObject> otherobjs, Type[] runningsnaptypes, Type usersnaptype)
{
return null;
}
public virtual string GetInfoAsString()
{
return string.Format("{1:D3} {0}@{2} - Type={3},",
this.Type,
No + 1,
Center.PosAsString(),
m_startAngle.ToString());
}
#endregion
#region ISerialize
public void GetObjectData(XmlWriter wr)
{
wr.WriteStartElement("Spline");
XmlUtil.WriteProperties(this, wr);
wr.WriteEndElement();
}
public virtual string GetObjectData()
{
string jsonString = string.Empty;
var options = new JsonSerializerOptions { WriteIndented = true };
try {
jsonString += JsonSerializer.Serialize(this, options);
} catch {
}
return jsonString;
}
public void AfterSerializedIn()
{
}
#endregion
}
}