329 lines
15 KiB
C#
329 lines
15 KiB
C#
using CoreUnit.Control.UserControl.Canvas;
|
|
using CoreUnit.Scanner.UserControl.ScannerCanvas;
|
|
using IxMilia.Dxf.Entities;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Drawing;
|
|
using System.Linq;
|
|
using System.Numerics;
|
|
using System.Security.Cryptography;
|
|
|
|
namespace GUI.Common
|
|
{
|
|
static class ParserHelper
|
|
{
|
|
static public AddObjectParam GetCandidate(
|
|
this AddObjectParam insert,
|
|
AddObjectParam nonInsert,
|
|
RectangleF rect)
|
|
{
|
|
var startPoint = new UnitPoint(
|
|
insert.Point1.X + rect.X,
|
|
insert.Point1.Y + rect.Y);
|
|
|
|
switch (nonInsert.ObjectType) {
|
|
case "ArcCR":
|
|
return new AddObjectParam {
|
|
ObjectType = "ArcCR",
|
|
Center = new UnitPoint(startPoint.X + nonInsert.MajorRadius, startPoint.Y + nonInsert.MajorRadius),
|
|
StartAngle = (float)0,
|
|
EndAngle = (float)360,
|
|
MajorRadius = (float)nonInsert.MajorRadius
|
|
};
|
|
case "Line":
|
|
return new AddObjectParam {
|
|
ObjectType = "Line",
|
|
Point1 = nonInsert.Point1 + startPoint,
|
|
Point2 = nonInsert.Point2 + startPoint,
|
|
};
|
|
case "Dot":
|
|
return new AddObjectParam {
|
|
ObjectType = "Dot",
|
|
Point1 = startPoint + nonInsert.Point1,
|
|
};
|
|
case "PolyLine":
|
|
return new AddObjectParam {
|
|
ObjectType = "Polyline",
|
|
Point1 = nonInsert.Point1 + startPoint,
|
|
Point2 = nonInsert.Point2 + startPoint,
|
|
};
|
|
case "Ellipse":
|
|
return new AddObjectParam {
|
|
ObjectType = "Ellipse",
|
|
Center = new UnitPoint(startPoint.X + nonInsert.MajorRadius, startPoint.Y + nonInsert.MajorRadius),
|
|
Point1 = startPoint + nonInsert.Point1,
|
|
Point2 = startPoint + nonInsert.Point1,
|
|
RotateAngle = nonInsert.RotateAngle
|
|
};
|
|
case "ZigZag":
|
|
return new AddObjectParam {
|
|
ObjectType = "ZigZag",
|
|
Point1 = nonInsert.Point1 + startPoint,
|
|
Point2 = nonInsert.Point2 + startPoint,
|
|
Pitch = nonInsert.Pitch,
|
|
Amplitude = nonInsert.Amplitude,
|
|
Radius = nonInsert.Radius,
|
|
RotateAngle = nonInsert.RotateAngle,
|
|
DrawDirection = nonInsert.DrawDirection
|
|
};
|
|
default:
|
|
Console.WriteLine($"Entity type: {nonInsert.ObjectType}");
|
|
return new AddObjectParam();
|
|
}
|
|
}
|
|
|
|
static public List<IDrawObject> AddObjects(
|
|
this IEnumerable<AddObjectParam> dataModelParams,
|
|
ScannerCanvasUserCtrl scannerCanvas)
|
|
{
|
|
var drawObjects = new List<IDrawObject>();
|
|
dataModelParams.ToList().ForEach(param =>
|
|
drawObjects.Add(scannerCanvas.AddObject(param)));
|
|
scannerCanvas.FinalizeGrouping();
|
|
return drawObjects;
|
|
}
|
|
static List<int> FindArcCloseToNextLine(IList<DxfEntity> entities, double pointTolerance)
|
|
{
|
|
// Arc의 시작점과 그 다음 Line의 시작점이 tolerance 이하일 경우 해당 Arc를 List에 저장
|
|
var arcIndices = new List<int>();
|
|
|
|
for (int i = 0; i < entities.Count - 1; i++) {
|
|
if (entities[i].EntityType == DxfEntityType.Arc &&
|
|
entities[i + 1].EntityType == DxfEntityType.Line) {
|
|
var arc = (DxfArc)entities[i];
|
|
var line = (DxfLine)entities[i + 1];
|
|
|
|
// Arc 시작점 계산
|
|
var arcStartX = arc.Center.X + arc.Radius * Math.Cos(DegreesToRadians(arc.StartAngle));
|
|
var arcStartY = arc.Center.Y + arc.Radius * Math.Sin(DegreesToRadians(arc.StartAngle));
|
|
|
|
// Line 시작점
|
|
var lineStartX = line.P1.X;
|
|
var lineStartY = line.P1.Y;
|
|
|
|
// 거리 계산
|
|
double dx = arcStartX - lineStartX;
|
|
double dy = arcStartY - lineStartY;
|
|
double dist = Math.Sqrt(dx * dx + dy * dy);
|
|
|
|
if (dist <= pointTolerance) {
|
|
arcIndices.Add(i); // 해당 Arc 인덱스 저장
|
|
}
|
|
}
|
|
}
|
|
|
|
return arcIndices;
|
|
}
|
|
static double DegreesToRadians(double degrees)
|
|
{
|
|
return degrees * Math.PI / 180.0;
|
|
}
|
|
static public IEnumerable<AddObjectParam> GetEntity(
|
|
this IList<DxfEntity> dxfEntities)
|
|
{
|
|
var dataModelParams = new List<AddObjectParam>();
|
|
|
|
// 1. Arc-다음 Line 시작점이 가까운 Arc 인덱스 찾기
|
|
var arcIndicesToCW = FindArcCloseToNextLine(dxfEntities, pointTolerance: 0.1);
|
|
|
|
// 2. 엔티티 처리
|
|
for (int i = 0; i < dxfEntities.Count; i++) {
|
|
var entity = dxfEntities[i];
|
|
bool isArcToCW = arcIndicesToCW.Contains(i);
|
|
|
|
switch (entity.EntityType) {
|
|
case DxfEntityType.Line:
|
|
var line = (DxfLine)entity;
|
|
Console.WriteLine($"Line from {line.P1} to {line.P2}");
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "Line",
|
|
Point1 = new UnitPoint(line.P1.X, line.P1.Y),
|
|
Point2 = new UnitPoint(line.P2.X, line.P2.Y)
|
|
});
|
|
break;
|
|
|
|
case DxfEntityType.Circle:
|
|
var circle = (DxfCircle)entity;
|
|
Console.WriteLine($"Circle with center {circle.Center} and radius {circle.Radius}");
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "ArcCR",
|
|
Center = new UnitPoint(circle.Center.X, circle.Center.Y),
|
|
StartAngle = 0f,
|
|
EndAngle = 360f,
|
|
MajorRadius = (float)circle.Radius
|
|
});
|
|
break;
|
|
|
|
case DxfEntityType.Arc:
|
|
var arc = (DxfArc)entity;
|
|
float startAngle = (float)Math.Round((float)arc.StartAngle, 0);
|
|
float endAngle = (float)Math.Round((float)arc.EndAngle, 0);
|
|
string direction = "CCW";
|
|
|
|
if (isArcToCW) {
|
|
direction = "CW";
|
|
// CW이면 Start/End 스왑
|
|
float temp = startAngle;
|
|
startAngle = endAngle;
|
|
endAngle = temp;
|
|
}
|
|
|
|
float sweepAngle = endAngle - startAngle;
|
|
if (direction == "CCW" && sweepAngle < 0) sweepAngle += 360;
|
|
if (direction == "CW" && sweepAngle > 0) sweepAngle -= 360;
|
|
|
|
Console.WriteLine($"Arc with center {arc.Center}, radius {arc.Radius}, start angle {startAngle}, end angle {endAngle}, direction {direction}");
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "ArcCR",
|
|
Center = new UnitPoint(arc.Center.X, arc.Center.Y),
|
|
StartAngle = startAngle,
|
|
EndAngle = endAngle,
|
|
SweepAngle = sweepAngle,
|
|
MajorRadius = (float)arc.Radius,
|
|
Direction = direction
|
|
});
|
|
break;
|
|
|
|
case DxfEntityType.LwPolyline:
|
|
var polyline = (DxfLwPolyline)entity;
|
|
Console.WriteLine($"LwPolyline with {polyline.Vertices.Count} vertices:");
|
|
for (int v = 0; v < polyline.Vertices.Count; v++) {
|
|
var vertex = polyline.Vertices[v];
|
|
var nextVertex = v < polyline.Vertices.Count - 1 ? polyline.Vertices[v + 1] : polyline.Vertices[0];
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "PolyLine",
|
|
Point1 = new UnitPoint(vertex.X, vertex.Y),
|
|
Point2 = new UnitPoint(nextVertex.X, nextVertex.Y)
|
|
});
|
|
}
|
|
break;
|
|
|
|
case DxfEntityType.Insert:
|
|
var insert = (DxfInsert)entity;
|
|
Console.WriteLine($"Insert block at position ({insert.Location.X}, {insert.Location.Y}, {insert.Location.Z})");
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "Insert",
|
|
Point1 = new UnitPoint(insert.Location.X, insert.Location.Y)
|
|
});
|
|
break;
|
|
|
|
case DxfEntityType.Ellipse:
|
|
var ellipse = (DxfEllipse)entity;
|
|
Console.WriteLine($"Ellipse with center {ellipse.Center}, major axis direction {ellipse.MajorAxis}, and normal {ellipse.Normal}, start {ellipse.StartParameter}, end {ellipse.EndParameter}");
|
|
var point1 = new UnitPoint(
|
|
ellipse.Center.X - ellipse.MajorAxis.Length,
|
|
ellipse.Center.Y - ellipse.MinorAxis().Length);
|
|
var point2 = new UnitPoint(
|
|
ellipse.Center.X + ellipse.MajorAxis.Length,
|
|
ellipse.Center.Y + ellipse.MinorAxis().Length);
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "Ellipse",
|
|
Center = new UnitPoint(ellipse.Center.X, ellipse.Center.Y),
|
|
Point1 = point1,
|
|
Point2 = point2,
|
|
StartAngle = (float)HitUtil.RadiansToDegrees(ellipse.StartParameter),
|
|
EndAngle = (float)HitUtil.RadiansToDegrees(ellipse.EndParameter),
|
|
RotateAngle = CalculateRotationAngle(ellipse)
|
|
});
|
|
break;
|
|
|
|
case DxfEntityType.Point:
|
|
var modelPoint = (DxfModelPoint)entity;
|
|
Console.WriteLine($"ModelPoint at ({modelPoint.Location.X}, {modelPoint.Location.Y}, {modelPoint.Location.Z})");
|
|
dataModelParams.Add(new AddObjectParam {
|
|
ObjectType = "Dot",
|
|
Point1 = new UnitPoint(modelPoint.Location.X, modelPoint.Location.Y),
|
|
});
|
|
break;
|
|
// 다른 도형 타입에 대한 처리 추가 가능
|
|
default:
|
|
Console.WriteLine($"Entity type: {entity.EntityType}");
|
|
break;
|
|
}
|
|
}
|
|
|
|
return dataModelParams;
|
|
}
|
|
static public RectangleF GetRect(
|
|
this IList<IDrawObject> drawObjects)
|
|
{
|
|
List<UnitPoint> ptList = new List<UnitPoint>();
|
|
|
|
drawObjects.ToList().ForEach(obj => {
|
|
switch (obj) {
|
|
case Line _:
|
|
ptList.Add(((Line)obj).P1);
|
|
ptList.Add(((Line)obj).P2);
|
|
break;
|
|
case Dot _:
|
|
ptList.Add(((Dot)obj).P1);
|
|
break;
|
|
case Spline _:
|
|
ptList.Add(((Spline)obj).Center);
|
|
break;
|
|
case SnowMan _:
|
|
ptList.Add(((SnowMan)obj).P1);
|
|
ptList.Add(((SnowMan)obj).P2);
|
|
break;
|
|
case Group _:
|
|
ptList.Add(((Group)obj).P1);
|
|
ptList.Add(((Group)obj).P2);
|
|
ptList.Add(((Group)obj).P3);
|
|
ptList.Add(((Group)obj).P4);
|
|
break;
|
|
case Arc3Point _: {
|
|
RectangleF tempRect = ((Arc3Point)obj).ClientRect;
|
|
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Top));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Top));
|
|
break;
|
|
}
|
|
case Arc _: {
|
|
RectangleF tempRect = ((Arc)obj).ClientRect;
|
|
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Top));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Top));
|
|
break;
|
|
}
|
|
case ZigZag _:
|
|
ptList.Add(((ZigZag)obj).P1);
|
|
ptList.Add(((ZigZag)obj).P2);
|
|
break;
|
|
case EllipseTool _: {
|
|
RectangleF tempRect = ((EllipseTool)obj).ClientRect;
|
|
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Top));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Top));
|
|
break;
|
|
}
|
|
case RectangleTool _: {
|
|
RectangleF tempRect = ((RectangleTool)obj).ClientRect;
|
|
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Left, tempRect.Top));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Bottom));
|
|
ptList.Add(new UnitPoint(tempRect.Right, tempRect.Top));
|
|
break;
|
|
}
|
|
}
|
|
});
|
|
return ScreenUtils.GetRect(ptList, 0);
|
|
}
|
|
|
|
static public float CalculateRotationAngle(
|
|
DxfEllipse ellipse)
|
|
{
|
|
// MajorAxis와 MinorAxis를 사용하여 회전 각도를 계산
|
|
var majorAxis = ellipse.MajorAxis;
|
|
float angle = (float)(Math.Atan2(majorAxis.Y, majorAxis.X) * (180.0 / Math.PI));
|
|
return angle;
|
|
}
|
|
}
|
|
}
|