using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using static Autodesk.AutoCAD.LayerManager.LayerFilter;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using DialogResult = System.Windows.Forms.DialogResult;
using Exception = Autodesk.AutoCAD.Runtime.Exception;
using SaveFileDialog = System.Windows.Forms.SaveFileDialog;
namespace QuadProcessor
{
public class QuadProcessor
{
[CommandMethod("GSHuoQuSiBianXingShuJu", CommandFlags.Modal)]
public void GSHuoQuSiBianXingShuJu()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
try
{
// 选择四边形(LWPOLYLINE)
PromptSelectionResult selRes = ed.GetSelection(new SelectionFilter(
new[] { new TypedValue(0, "LWPOLYLINE") }));
if (selRes.Status != PromptStatus.OK)
{
ed.WriteMessage("\n操作已取消。");
return;
}
int totalCount = selRes.Value.Count;
int processedCount = 0;
int skippedCount = 0;
var results = new List<QuadResult>();
// +++ 修改:使用句柄作为键 +++
var errors = new Dictionary<string, string>(); // 键为句柄字符串
var skipReasons = new Dictionary<string, string>();
Stopwatch sw = Stopwatch.StartNew();
ObjectId[] ids = selRes.Value.GetObjectIds();
// 获取排序选项
var sortOption = GetSortOption(ed);
if (sortOption == null) return; // 用户取消
// 使用文档锁确保线程安全
using (DocumentLock docLock = doc.LockDocument())
using (Transaction tr = db.TransactionManager.StartTransaction())
{
// 单线程处理所有选择的四边形
for (int i = 0; i < ids.Length; i++)
{
ObjectId id = ids[i];
string handle = id.Handle.ToString(); // +++ 新增:在事务内获取句柄 +++
try
{
Polyline pl = tr.GetObject(id, OpenMode.ForRead) as Polyline;
if (pl != null)
{
if (pl.NumberOfVertices == 4 && pl.Closed)
{
string skipReason;
string textContent = GetTextInsidePolyline(tr, pl);
var result = ProcessQuad(pl, out skipReason, textContent, i + 1);
if (result != null)
{
results.Add(result);
processedCount++;
}
else
{
skippedCount++;
skipReasons[handle] = skipReason ?? "未知原因跳过"; // +++ 修改:使用句柄作为键 +++
}
}
else
{
skippedCount++;
skipReasons[handle] = "不是四边形(顶点数不为4或未闭合)"; // +++ 修改:使用句柄作为键 +++
}
}
else
{
skippedCount++;
skipReasons[handle] = "所选对象不是多段线"; // +++ 修改:使用句柄作为键 +++
}
}
catch (Exception ex)
{
errors[handle] = $"处理失败: {ex.Message}"; // +++ 修改:使用句柄作为键 +++
}
}
tr.Commit();
} // 这里会自动解锁文档
// 按用户选择的排序方式排序结果
SortResults(results, sortOption.Value);
// 获取默认桌面路径
string defaultPath = Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.Desktop),
"InformationExport.csv");//保存文件名
// 显示保存文件对话框
string csvPath = ShowSaveFileDialog(defaultPath);
if (csvPath != null)
{
// 导出结果
ExportToCSV(results, csvPath);
// 显示统计信息
ed.WriteMessage($"\n处理完成: " +
// ... 统计信息 ...
$"\n结果已保存至: {csvPath}");
//// +++ 新增:询问是否打开文件方案一 +++
//PromptKeywordOptions openOptions = new PromptKeywordOptions("\n是否打开结果文件? [是(Y)/否(N)] <是>: ");
//openOptions.Keywords.Add("是", "Y", "Y");
//openOptions.Keywords.Add("否", "N", "N");
//openOptions.Keywords.Default = "是";
//openOptions.AllowNone = true;
//PromptResult openRes = ed.GetKeywords(openOptions);
//if (openRes.Status == PromptStatus.OK && openRes.StringResult == "是")
//{
// try
// {
// Process.Start(new ProcessStartInfo(csvPath) { UseShellExecute = true });
// }
// catch (Exception ex)
// {
// ed.WriteMessage($"\n打开文件失败: {ex.Message}");
// }
//}
// +++ 新增:询问是否打开文件方案一 结束+++
// 询问是否打开文件方案二
ed.WriteMessage("\n\n**********************************************");
ed.WriteMessage("\n* 是否打开结果文件? [是(Y)/否(N)] <是>: *");
ed.WriteMessage("\n**********************************************");
PromptKeywordOptions openOptions = new PromptKeywordOptions("");
openOptions.Keywords.Add("是", "Y", "Y");
openOptions.Keywords.Add("否", "N", "N");
openOptions.Keywords.Default = "是";
openOptions.AllowNone = true;//
PromptResult openRes = ed.GetKeywords(openOptions);
if (openRes.Status == PromptStatus.OK && openRes.StringResult == "是")
{
try
{
Process.Start(new ProcessStartInfo(csvPath) { UseShellExecute = true });
}
catch (Exception ex)
{
ed.WriteMessage($"\n打开文件失败: {ex.Message}");
}
}
// 询问是否打开文件方案二结束
// 显示统计信息
ed.WriteMessage($"\n处理完成: " +
$"\n总四边形数: {totalCount} " +
$"\n成功处理: {processedCount} " +
$"\n跳过: {skippedCount} " +
$"\n错误: {errors.Count} " +
$"\n耗时: {sw.Elapsed.TotalSeconds:F2}秒" +
$"\n结果已保存至: {csvPath}");
}
else
{
ed.WriteMessage("\n操作已取消,未保存结果。");
}
// +++ 修改:在处理结束后添加错误日志记录 +++
if (errors.Count > 0 || skipReasons.Count > 0)
{
// 创建日志文件路径
string logDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
string logFileName = $"gs_{DateTime.Now:yyyyMMddHHmmss}.log";
string logPath = Path.Combine(logDir, logFileName);
using (StreamWriter logWriter = new StreamWriter(logPath))
{
logWriter.WriteLine($"四边形处理日志 - {DateTime.Now}");
logWriter.WriteLine("=================================");
// 写入错误信息
if (errors.Count > 0)
{
logWriter.WriteLine("\n错误详情:");
foreach (var error in errors)
{
logWriter.WriteLine($"句柄 {error.Key}: {error.Value}");
}
}
// 写入跳过信息
if (skipReasons.Count > 0)
{
logWriter.WriteLine("\n跳过详情:");
foreach (var skip in skipReasons)
{
logWriter.WriteLine($"句柄 {skip.Key}: {skip.Value}");
}
}
}
ed.WriteMessage($"\n详细错误和跳过信息已保存至: {logPath}");
}
// 显示错误信息
if (errors.Count > 0)
{
ed.WriteMessage("\n\n错误详情:");
foreach (var error in errors)
{
ed.WriteMessage($"\n句柄 {error.Key}: {error.Value}");
}
}
// 显示跳过信息
if (skipReasons.Count > 0)
{
ed.WriteMessage("\n\n跳过详情:");
foreach (var skip in skipReasons)
{
ed.WriteMessage($"\n句柄 {skip.Key}: {skip.Value}");
}
}
}
catch (Exception ex)
{
ed.WriteMessage($"\n错误: {ex.Message}");
}
}
private SortOption? GetSortOption(Editor ed)
{
var options = new PromptKeywordOptions("\n选择排序方式 [图形编号(G)/选择顺序(S)/坐标位置(C)/序号(N)] <图形编号>: ");
// 添加关键字和别名
options.Keywords.Add("图形编号", "G", "G"); // 全名 + 别名
options.Keywords.Add("选择顺序", "S", "S");
options.Keywords.Add("坐标位置", "C", "C");
options.Keywords.Add("序号", "N", "N");
options.Keywords.Default = "图形编号";
options.AllowNone = true;
var res = ed.GetKeywords(options);
if (res.Status != PromptStatus.OK) return null;
// 根据用户输入返回排序选项
switch (res.StringResult)
{
case "图形编号":
case "G": return SortOption.TextID;
case "选择顺序":
case "S": return SortOption.SelectionOrder;
case "坐标位置":
case "C": return SortOption.Coordinate;
case "序号":
case "N": return SortOption.SequenceNumber;
default: return SortOption.TextID; // 默认为图形编号
}
}
private void SortResults(List<QuadResult> results, SortOption sortOption)
{
switch (sortOption)
{
case SortOption.SequenceNumber:
// 保持原始处理顺序
break;
case SortOption.SelectionOrder:
// 选择顺序就是处理顺序,不需要排序
break;
case SortOption.Coordinate:
// 先按X坐标排序,X相同再按Y坐标排序
results.Sort((a, b) =>
{
int cmp = a.CenterX.CompareTo(b.CenterX);
return cmp != 0 ? cmp : a.CenterY.CompareTo(b.CenterY);
});
break;
case SortOption.TextID:
// 使用自然排序比较器
results.Sort(new NaturalStringComparer());
break;
}
// +++ 新增:排序后重新设置序号 +++
for (int i = 0; i < results.Count; i++)
{
results[i].SequenceNumber = i + 1;
}
}
// 自然排序比较器(解决1,10,2排序问题)
public class NaturalStringComparer : IComparer<QuadResult>
{
public int Compare(QuadResult x, QuadResult y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
return CompareNatural(x.TextContent, y.TextContent);
}
private int CompareNatural(string strA, string strB)
{
if (strA == null && strB == null) return 0;
if (strA == null) return -1;
if (strB == null) return 1;
int indexA = 0;
int indexB = 0;
while (indexA < strA.Length && indexB < strB.Length)
{
if (char.IsDigit(strA[indexA]) && char.IsDigit(strB[indexB]))
{
// 提取数字部分
string numStrA = ExtractNumber(strA, ref indexA);
string numStrB = ExtractNumber(strB, ref indexB);
if (int.TryParse(numStrA, out int numA) && int.TryParse(numStrB, out int numB))
{
int numCompare = numA.CompareTo(numB);
if (numCompare != 0) return numCompare;
}
else
{
// 如果解析失败,按字符串比较
int strCompare = string.Compare(numStrA, numStrB, StringComparison.Ordinal);
if (strCompare != 0) return strCompare;
}
}
else
{
// 非数字部分比较
int charCompare = strA[indexA].CompareTo(strB[indexB]);
if (charCompare != 0) return charCompare;
indexA++;
indexB++;
}
}
// 比较长度
return strA.Length.CompareTo(strB.Length);
}
private string ExtractNumber(string str, ref int index)
{
int start = index;
while (index < str.Length && char.IsDigit(str[index]))
{
index++;
}
return str.Substring(start, index - start);
}
}
private string ShowSaveFileDialog(string defaultPath)
{
try
{
// 使用Windows Forms的保存文件对话框
SaveFileDialog saveDialog = new SaveFileDialog();
saveDialog.Title = "导出四边形分析结果";
saveDialog.Filter = "CSV文件 (*.csv)|*.csv|所有文件 (*.*)|*.*";
saveDialog.FileName = Path.GetFileName(defaultPath);
saveDialog.InitialDirectory = Path.GetDirectoryName(defaultPath);
saveDialog.DefaultExt = ".csv";
saveDialog.AddExtension = true;
// 设置AutoCAD主窗口为父窗口
IntPtr acadWindow = Application.MainWindow.Handle;
if (acadWindow != IntPtr.Zero)
{
System.Windows.Forms.IWin32Window owner =
new WindowWrapper(acadWindow);
if (saveDialog.ShowDialog(owner) == DialogResult.OK)
{
return saveDialog.FileName;
}
}
else
{
// 如果没有找到AutoCAD主窗口,直接显示对话框
if (saveDialog.ShowDialog() == DialogResult.OK)
{
return saveDialog.FileName;
}
}
}
catch (Exception)
{
// 如果对话框失败,使用默认路径
return defaultPath;
}
return null; // 用户取消
}
// 获取多边形内部的文字内容(改进版)
private string GetTextInsidePolyline(Transaction tr, Polyline pl)
{
try
{
// 获取多边形的几何范围
Extents3d extents = pl.GeometricExtents;
Point3d minPoint = extents.MinPoint;
Point3d maxPoint = extents.MaxPoint;
// 创建选择框
Point3dCollection points = new Point3dCollection
{
minPoint,
new Point3d(maxPoint.X, minPoint.Y, minPoint.Z),
maxPoint,
new Point3d(minPoint.X, maxPoint.Y, minPoint.Z),
minPoint
};
// 创建选择过滤器
TypedValue[] filterList = new TypedValue[]
{
new TypedValue(0, "TEXT,MTEXT")
};
SelectionFilter filter = new SelectionFilter(filterList);
// 选择多边形内部的文字
PromptSelectionResult selRes = Application.DocumentManager.MdiActiveDocument.Editor.SelectCrossingPolygon(points, filter);
if (selRes.Status == PromptStatus.OK)
{
SelectionSet selectionSet = selRes.Value;
List<TextInfo> textInfos = new List<TextInfo>();
foreach (SelectedObject selectedObject in selectionSet)
{
using (DBObject dbObj = tr.GetObject(selectedObject.ObjectId, OpenMode.ForRead))
{
Point3d position = Point3d.Origin;
string text = "";
if (dbObj is DBText dbText)
{
position = dbText.Position;
text = dbText.TextString;
}
else if (dbObj is MText mText)
{
position = mText.Location;
text = mText.Text;
}
if (!string.IsNullOrEmpty(text))
{
textInfos.Add(new TextInfo
{
Position = position,
Text = text,
DistanceToCenter = GetDistanceToPolylineCenter(pl, position)
});
}
}
}
// 如果没有文字,返回空
if (textInfos.Count == 0) return "";
// 找到最靠近四边形中心的文字
var closestText = textInfos.OrderBy(t => t.DistanceToCenter).First();
return closestText.Text;
}
}
catch
{
// 忽略错误
}
return "";
}
// 计算点到四边形中心的距离
private double GetDistanceToPolylineCenter(Polyline pl, Point3d point)
{
// 计算四边形中心点
double centerX = 0, centerY = 0;
for (int i = 0; i < 4; i++)
{
Point2d pt = pl.GetPoint2dAt(i);
centerX += pt.X;
centerY += pt.Y;
}
centerX /= 4;
centerY /= 4;
// 计算距离
double dx = point.X - centerX;
double dy = point.Y - centerY;
return Math.Sqrt(dx * dx + dy * dy);
}
// 顶点排序方法 - 根据用户描述实现
private Point2d[] ReorderVertices(Polyline pl, out string error)
{
error = null;
try
{
// 获取原始四个顶点
Point2d[] points = new Point2d[4];
for (int i = 0; i < 4; i++)
points[i] = pl.GetPoint2dAt(i);
// 1. 找到X最小的两个点
var sortedByX = points.OrderBy(p => p.X).ToArray();
Point2d[] minXPoints = new Point2d[] { sortedByX[0], sortedByX[1] };
// 2. 在X最小的两个点中,找到Y最小的点作为左下角(第一个点)
var sortedMinX = minXPoints.OrderBy(p => p.Y).ToArray();
Point2d bottomLeft = sortedMinX[0]; // 左下角
Point2d topLeft = sortedMinX[1]; // 左上角
// 3. 剩下的两个点
Point2d[] remainingPoints = points.Except(minXPoints).ToArray();
// 4. 在剩下的两个点中,找到Y最小的点作为右下角(第二个点)
var sortedRemaining = remainingPoints.OrderBy(p => p.Y).ToArray();
Point2d bottomRight = sortedRemaining[0]; // 右下角
Point2d topRight = sortedRemaining[1]; // 右上角
// 返回排序后的顶点:左下、右下、右上、左上
return new Point2d[] { bottomLeft, bottomRight, topRight, topLeft };
}
catch (Exception ex)
{
error = $"顶点排序失败: {ex.Message}";
return null;
}
}
// 处理四边形
private QuadResult ProcessQuad(Polyline pl, out string skipReason, string textContent, int sequenceNumber)
{
skipReason = null;
try
{
// 重新排序顶点(左下角起始,逆时针)
string error;
Point2d[] pts = ReorderVertices(pl, out error);
if (pts == null)
{
skipReason = error ?? "顶点排序失败";
return null;
}
// 验证顶点顺序
if (pts.Length != 4)
{
skipReason = "顶点数不足4个";
return null;
}
// 计算中心点(用于排序)
double centerX = pts.Average(p => p.X);
double centerY = pts.Average(p => p.Y);
// 计算边长(逆时针顺序)
double side1 = pts[0].GetDistanceTo(pts[1]); // 左下→右下
double side2 = pts[1].GetDistanceTo(pts[2]); // 右下→右上
double side3 = pts[2].GetDistanceTo(pts[3]); // 右上→左上
double side4 = pts[3].GetDistanceTo(pts[0]); // 左上→左下
// 计算对角线
double diag1 = pts[0].GetDistanceTo(pts[2]); // 左下→右上
double diag2 = pts[1].GetDistanceTo(pts[3]); // 右下→左上
// 计算最小外接矩形
var obb = CalculateOBB(pts, out error);
if (obb == null)
{
skipReason = error ?? "无法计算最小外接矩形";
return null;
}
return new QuadResult(
sequenceNumber,
pl.ObjectId,
textContent,
side1, side2, side3, side4,
diag1, diag2,
obb.Width, obb.Height,
centerX, centerY);
}
catch (Exception ex)
{
skipReason = $"处理失败: {ex.Message}";
return null;
}
}
private OBBResult CalculateOBB(Point2d[] points, out string error)
{
error = null;
try
{
// 计算凸包(确保处理非凸四边形)
var hull = CalculateConvexHull(points);
if (hull == null || hull.Count < 3)
{
error = "无法计算凸包";
return null;
}
double minArea = double.MaxValue;
double width = 0, height = 0;
// 检查凸包点数,处理三角形退化情况
int hullCount = hull.Count;
if (hullCount == 3)
{
// 三角形处理:计算最小包围矩形
return ProcessTriangle(hull);
}
// 旋转卡壳算法求OBB
for (int i = 0; i < hullCount; i++)
{
Vector2d edge = hull[(i + 1) % hullCount] - hull[i];
double edgeLength = edge.Length;
if (edgeLength < 1e-9) continue; // 跳过零长度边
Vector2d edgeDir = edge / edgeLength; // 单位化向量
// 计算旋转角度
double angle = Math.Atan2(edgeDir.Y, edgeDir.X);
Matrix2d rot = Matrix2d.Rotation(-angle, Point2d.Origin);
// 计算旋转后的边界
double minX = double.MaxValue, maxX = double.MinValue;
double minY = double.MaxValue, maxY = double.MinValue;
for (int j = 0; j < hullCount; j++)
{
Point2d rotatedPt = hull[j].TransformBy(rot);
if (rotatedPt.X < minX) minX = rotatedPt.X;
if (rotatedPt.X > maxX) maxX = rotatedPt.X;
if (rotatedPt.Y < minY) minY = rotatedPt.Y;
if (rotatedPt.Y > maxY) maxY = rotatedPt.Y;
}
double w = maxX - minX;
double h = maxY - minY;
double area = w * h;
if (area < minArea)
{
minArea = area;
width = w;
height = h;
}
}
return new OBBResult(width, height);
}
catch (Exception ex)
{
error = $"OBB计算失败: {ex.Message}";
return null;
}
}
private List<Point2d> CalculateConvexHull(Point2d[] points)
{
try
{
// 少于3个点直接返回
if (points.Length < 3) return new List<Point2d>(points);
// 按X坐标排序
var sortedPoints = points.OrderBy(p => p.X).ThenBy(p => p.Y).ToArray();
// 构建下凸包
List<Point2d> lowerHull = new List<Point2d>();
for (int i = 0; i < sortedPoints.Length; i++)
{
while (lowerHull.Count >= 2 &&
Cross(lowerHull[lowerHull.Count - 2], lowerHull[lowerHull.Count - 1], sortedPoints[i]) <= 0)
{
lowerHull.RemoveAt(lowerHull.Count - 1);
}
lowerHull.Add(sortedPoints[i]);
}
// 构建上凸包
List<Point2d> upperHull = new List<Point2d>();
for (int i = sortedPoints.Length - 1; i >= 0; i--)
{
while (upperHull.Count >= 2 &&
Cross(upperHull[upperHull.Count - 2], upperHull[upperHull.Count - 1], sortedPoints[i]) <= 0)
{
upperHull.RemoveAt(upperHull.Count - 1);
}
upperHull.Add(sortedPoints[i]);
}
// 合并凸包(移除重复点)
if (lowerHull.Count > 0) lowerHull.RemoveAt(lowerHull.Count - 1);
if (upperHull.Count > 0) upperHull.RemoveAt(upperHull.Count - 1);
lowerHull.AddRange(upperHull);
return lowerHull;
}
catch
{
return null;
}
}
private OBBResult ProcessTriangle(List<Point2d> triangle)
{
// 计算三角形的最小包围矩形
double minArea = double.MaxValue;
double width = 0, height = 0;
// 尝试三个边方向
for (int i = 0; i < 3; i++)
{
Vector2d edge = triangle[(i + 1) % 3] - triangle[i];
double edgeLength = edge.Length;
if (edgeLength < 1e-9) continue; // 跳过零长度边
Vector2d edgeDir = edge / edgeLength;
double angle = Math.Atan2(edgeDir.Y, edgeDir.X);
Matrix2d rot = Matrix2d.Rotation(-angle, Point2d.Origin);
// 计算旋转后的边界
double minX = double.MaxValue, maxX = double.MinValue;
double minY = double.MaxValue, maxY = double.MinValue;
for (int j = 0; j < 3; j++)
{
Point2d rotatedPt = triangle[j].TransformBy(rot);
if (rotatedPt.X < minX) minX = rotatedPt.X;
if (rotatedPt.X > maxX) maxX = rotatedPt.X;
if (rotatedPt.Y < minY) minY = rotatedPt.Y;
if (rotatedPt.Y > maxY) maxY = rotatedPt.Y;
}
double w = maxX - minX;
double h = maxY - minY;
double area = w * h;
if (area < minArea)
{
minArea = area;
width = w;
height = h;
}
}
return new OBBResult(width, height);
}
private double Cross(Point2d a, Point2d b, Point2d c)
{
return (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X);
}
private void ExportToCSV(IEnumerable<QuadResult> results, string path)
{
try
{
using (StreamWriter sw = new StreamWriter(path))
{
sw.WriteLine("序号,对象句柄,图形编号,边1,边2,边3,边4,对角线1,对角线2,最小外接矩形宽度,最小外接矩形高度,中心点X,中心点Y");
foreach (var r in results)
{
sw.WriteLine($"{r.SequenceNumber}," +
$"{r.Handle}," +
$"\"{r.TextContent}\"," +
$"{r.Side1:F0},{r.Side2:F0},{r.Side3:F0},{r.Side4:F0}," +
$"{r.Diagonal1:F0},{r.Diagonal2:F0}," +
$"{r.OBBWidth:F0},{r.OBBHeight:F0}," +
$"{r.CenterX:F0},{r.CenterY:F0}");
}
}
}
catch (Exception ex)
{
Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(
$"\n保存文件时出错: {ex.Message}");
}
}
}
// 文字信息辅助类
public class TextInfo
{
public Point3d Position { get; set; }
public string Text { get; set; }
public double DistanceToCenter { get; set; }
}
// 排序选项枚举
public enum SortOption
{
TextID, // 图形编号(默认)
SelectionOrder, // 选择顺序
Coordinate, // 坐标位置(先X后Y)
SequenceNumber // 序号
}
// 结果数据结构
public class QuadResult
{
public int SequenceNumber { get; set; } // 序号
public string Handle { get; }
public string TextContent { get; } // 图形内部文字内容
public double Side1 { get; }
public double Side2 { get; }
public double Side3 { get; }
public double Side4 { get; }
public double Diagonal1 { get; }
public double Diagonal2 { get; }
public double OBBWidth { get; }
public double OBBHeight { get; }
public double CenterX { get; } // 中心点X坐标
public double CenterY { get; } // 中心点Y坐标
public QuadResult(
int sequenceNumber,
ObjectId objectId,
string textContent,
double side1, double side2, double side3, double side4,
double diag1, double diag2,
double width, double height,
double centerX, double centerY)
{
SequenceNumber = sequenceNumber;
Handle = objectId.Handle.ToString();
TextContent = textContent ?? "";
Side1 = side1;
Side2 = side2;
Side3 = side3;
Side4 = side4;
Diagonal1 = diag1;
Diagonal2 = diag2;
OBBWidth = width;
OBBHeight = height;
CenterX = centerX;
CenterY = centerY;
}
}
public class OBBResult
{
public double Width { get; }
public double Height { get; }
public OBBResult(double width, double height)
{
Width = width;
Height = height;
}
}
// 包装AutoCAD窗口的辅助类
public class WindowWrapper : System.Windows.Forms.IWin32Window
{
private readonly IntPtr _hwnd;
public WindowWrapper(IntPtr handle)
{
_hwnd = handle;
}
public IntPtr Handle
{
get { return _hwnd; }
}
}
}把代码里面方法名修改下,避免二次调用
最新发布