using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
public class CADUtilities
{
// 常量定义
private const double OverlapThreshold = 10.0; // 毫米
private const double ConcreteDensity = 25.0; // 混凝土容重(kN/m³)
// ================== 梁信息类 ==================
private class BeamInfo
{
public ObjectId Id { get; set; }
public Extents3d Extents { get; set; }
public Vector3d Direction { get; set; }
public Point3d Center { get; set; }
public bool IsHorizontal { get; set; }
}
// ================== 梁尺寸信息类 ==================
private class BeamSizeInfo
{
public string Size { get; set; }
public int Count { get; set; }
public double Width { get; set; }
public double Height { get; set; }
public double Area { get; set; }
public double LineLoad { get; set; }
}
// ================== CLN - 清理无用实体命令(增强版) ==================
[CommandMethod("CLN")]
public void CleanUpDrawing()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null) return;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
int deletedCount = 0;
var idsToDelete = new List<ObjectId>();
foreach (ObjectId id in btr)
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent == null) continue;
// 处理文本实体
if (ent is DBText text)
{
string textStr = text.TextString;
// 保留所有重要文本(轴号、标高、梁编号、尺寸标注)
if (IsAxisNumber(textStr) ||
textStr.Contains("标高") ||
IsBeamLabel(textStr) ||
IsBeamDimension(textStr))
{
continue; // 保留这些文本
}
// 删除空文本和非重要文本
if (string.IsNullOrWhiteSpace(textStr) ||
textStr.Length < 2 || // 删除过短文本
textStr == " " || // 删除空格文本
textStr == ".")
{
idsToDelete.Add(id);
continue;
}
}
// 处理多行文本
else if (ent is MText mtext)
{
string textStr = mtext.Text;
if (string.IsNullOrWhiteSpace(textStr) ||
textStr.Length < 2)
{
idsToDelete.Add(id);
continue;
}
}
// 删除零长度线
else if (ent is Line line && line.Length < 0.001)
{
idsToDelete.Add(id);
}
// 删除零长度多段线
else if (ent is Polyline pline && pline.Length < 0.001)
{
idsToDelete.Add(id);
}
// 删除孤立点
else if (ent is DBPoint point)
{
idsToDelete.Add(id);
}
}
// 执行删除操作
foreach (ObjectId id in idsToDelete)
{
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
ent.Erase(true); // 使用Erase(true)确保立即删除
deletedCount++;
}
tr.Commit();
ed.WriteMessage($"\n清理完成,删除 {deletedCount} 个无用实体");
}
}
// ================== DEL - 图层删除命令 ==================
[CommandMethod("DEL")]
public void DeleteByLayer()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null) return;
Database db = doc.Database;
Editor ed = doc.Editor;
// 用户选择参考对象
PromptEntityOptions opt = new PromptEntityOptions("\n选择图层参考对象:");
PromptEntityResult res = ed.GetEntity(opt);
if (res.Status != PromptStatus.OK) return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
// 获取目标图层
Entity refEnt = tr.GetObject(res.ObjectId, OpenMode.ForRead) as Entity;
if (refEnt == null) return;
string targetLayer = refEnt.Layer;
// 收集当前空间所有实体
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
List<ObjectId> toDelete = new List<ObjectId>();
foreach (ObjectId id in btr)
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent != null && ent.Layer == targetLayer)
{
toDelete.Add(id);
}
}
// 执行删除
if (toDelete.Count > 0)
{
foreach (ObjectId id in toDelete)
{
Entity ent = (Entity)tr.GetObject(id, OpenMode.ForWrite);
ent.Erase();
}
tr.Commit();
ed.WriteMessage($"\n已删除图层 '{targetLayer}' 中的 {toDelete.Count} 个对象");
}
else
{
ed.WriteMessage($"\n图层 '{targetLayer}' 中未找到可删除对象");
}
}
catch (System.Exception ex)
{
ed.WriteMessage($"\n错误: {ex.Message}");
tr.Abort();
}
}
}
// ================== BST - 梁截面统计命令(增强版) ==================
[CommandMethod("BST")]
public void BeamStatisticsSortedByLoad()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
if (doc == null) return;
Database db = doc.Database;
Editor ed = doc.Editor;
// 提示用户框选范围
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\n框选要统计的梁实体和标注文本: ";
PromptSelectionResult psr = ed.GetSelection(pso);
if (psr.Status != PromptStatus.OK) return;
// 增强的梁尺寸正则表达式 - 支持多种格式
Regex sizeRegex = new Regex(@"(\d{2,4})\s*[xX×]\s*(\d{2,4})", RegexOptions.Compiled);
// 存储原始尺寸统计结果
Dictionary<string, int> sizeCounts = new Dictionary<string, int>(StringComparer.OrdinalIgnoreCase);
using (Transaction tr = db.TransactionManager.StartTransaction())
{
try
{
// 处理选中的实体
foreach (ObjectId id in psr.Value.GetObjectIds())
{
Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
if (ent == null) continue;
// 处理文本实体
if (ent is DBText text)
{
string textStr = text.TextString;
// 尝试提取尺寸 - 支持多种格式
Match match = sizeRegex.Match(textStr);
if (match.Success)
{
string size = $"{match.Groups[1].Value}x{match.Groups[2].Value}";
AddSizeToDictionary(sizeCounts, size);
}
// 尝试提取梁编号中的尺寸
else if (IsBeamLabel(textStr))
{
Match sizeMatch = ExtractSizeFromBeamLabel(textStr);
if (sizeMatch.Success)
{
string size = $"{sizeMatch.Groups[1].Value}x{sizeMatch.Groups[2].Value}";
AddSizeToDictionary(sizeCounts, size);
}
}
}
// 处理多行文本
else if (ent is MText mtext)
{
string textStr = mtext.Text;
MatchCollection matches = sizeRegex.Matches(textStr);
foreach (Match match in matches)
{
string size = $"{match.Groups[1].Value}x{match.Groups[2].Value}";
AddSizeToDictionary(sizeCounts, size);
}
}
}
// 如果没有找到尺寸信息
if (sizeCounts.Count == 0)
{
ed.WriteMessage("\n未找到有效的梁尺寸信息!");
tr.Abort();
return;
}
// 提示用户输入表格插入点
PromptPointOptions ppo = new PromptPointOptions("\n指定统计表插入点: ");
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK) return;
Point3d insertPoint = ppr.Value;
// 创建并排序梁尺寸信息列表
List<BeamSizeInfo> sortedBeamInfo = CreateSortedBeamInfo(sizeCounts);
// 创建统计表格
CreateBeamStatisticsTable(tr, db, insertPoint, sortedBeamInfo);
tr.Commit();
ed.WriteMessage($"\n已创建包含 {sizeCounts.Count} 种梁尺寸的统计表,按线荷载值降序排列");
}
catch (System.Exception ex)
{
ed.WriteMessage($"\n创建表格时出错: {ex.Message}\n{ex.StackTrace}");
tr.Abort();
}
}
}
// ================== 创建统计表(修复版) ==================
private void CreateBeamStatisticsTable(
Transaction tr, Database db, Point3d insertPoint, List<BeamSizeInfo> beamInfoList)
{
try
{
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
db.CurrentSpaceId, OpenMode.ForWrite);
// 创建表格对象
Table table = new Table();
table.Position = insertPoint;
// 设置表格尺寸(行数 = 标题行 + 表头行 + 数据行 + 汇总行 + 备注行)
int dataRows = beamInfoList.Count;
int totalRows = 4 + dataRows; // 标题行(0) + 表头行(1) + 数据行(2..n) + 汇总行(n+1) + 备注行(n+2)
int columns = 5;
table.SetSize(totalRows, columns);
table.SetRowHeight(8); // 行高
table.SetColumnWidth(15); // 列宽
// 确保表格样式存在
if (db.Tablestyle == ObjectId.Null)
{
// 创建默认表格样式
table.TableStyle = CreateDefaultTableStyle(db, tr);
}
else
{
table.TableStyle = db.Tablestyle;
}
table.Layer = "统计表";
table.ColorIndex = 0; // ByLayer
// === 设置标题行 ===
table.Cells[0, 0].Value = "梁截面尺寸统计表(按线荷载排序)";
table.Cells[0, 0].Alignment = CellAlignment.MiddleCenter;
table.MergeCells(CellRange.Create(table, 0, 0, 0, columns - 1)); // 合并标题行
table.Rows[0].Height = 15; // 标题行高度
// === 设置表头行 ===
string[] headers = { "序号", "梁截面尺寸(mm)", "出现数量", "截面面积(㎡)", "梁线荷载(kN/m)" };
for (int col = 0; col < columns; col++)
{
table.Cells[1, col].Value = headers[col];
table.Cells[1, col].Alignment = CellAlignment.MiddleCenter;
table.Cells[1, col].BackgroundColor = Color.FromColorIndex(ColorMethod.ByAci, 5); // 蓝色背景
table.Cells[1, col].TextHeight = 3.5; // 设置文字高度
}
// === 填充数据行 ===
int rowIndex = 2;
int sequence = 1;
double totalArea = 0;
double totalLoad = 0;
foreach (BeamSizeInfo info in beamInfoList)
{
// 确保行索引有效
if (rowIndex >= totalRows) break;
// 填充表格数据
table.Cells[rowIndex, 0].Value = sequence.ToString(); // 序号
table.Cells[rowIndex, 1].Value = info.Size; // 尺寸
table.Cells[rowIndex, 2].Value = info.Count.ToString(); // 数量
table.Cells[rowIndex, 3].Value = info.Area.ToString("F4"); // 面积
table.Cells[rowIndex, 4].Value = info.LineLoad.ToString("F2"); // 荷载
// 设置荷载列文本颜色
if (info.LineLoad > 10) // 高荷载用红色
table.Cells[rowIndex, 4].ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 1);
else if (info.LineLoad > 5) // 中等荷载用黄色
table.Cells[rowIndex, 4].ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 2);
else // 低荷载用绿色
table.Cells[rowIndex, 4].ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 3);
// 累计汇总值
totalArea += info.Area * info.Count;
totalLoad += info.LineLoad * info.Count;
sequence++;
rowIndex++;
}
// === 添加汇总行 ===
int summaryRow = rowIndex;
if (summaryRow < totalRows)
{
table.Cells[summaryRow, 0].Value = "汇总";
table.Cells[summaryRow, 0].Alignment = CellAlignment.MiddleCenter;
table.MergeCells(CellRange.Create(table, summaryRow, 0, summaryRow, 1)); // 合并前两列
table.Cells[summaryRow, 2].Value = beamInfoList.Sum(b => b.Count).ToString();
table.Cells[summaryRow, 3].Value = totalArea.ToString("F4");
table.Cells[summaryRow, 4].Value = totalLoad.ToString("F2");
// 设置汇总行文本颜色
for (int col = 0; col < columns; col++)
{
table.Cells[summaryRow, col].ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 1); // 红色
}
}
// === 添加备注行 ===
int remarkRow = summaryRow + 1;
if (remarkRow < totalRows)
{
table.Cells[remarkRow, 0].Value = "备注:表中线荷载值仅做参考值";
table.Cells[remarkRow, 0].Alignment = CellAlignment.MiddleLeft;
table.MergeCells(CellRange.Create(table, remarkRow, 0, remarkRow, columns - 1)); // 合并整行
table.Cells[remarkRow, 0].TextHeight = 6; // 设置较小的字体大小
table.Cells[remarkRow, 0].ContentColor = Color.FromColorIndex(ColorMethod.ByAci, 2); // 绿色
// 设置备注行高度(略低于其他行)
table.Rows[remarkRow].Height = 6;
}
// 添加表格到图形
btr.AppendEntity(table);
tr.AddNewlyCreatedDBObject(table, true);
}
catch (System.Exception ex)
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
ed.WriteMessage($"\n创建表格时出错: {ex.Message}\n{ex.StackTrace}");
}
}
// ================== 创建默认表格样式 ==================
private ObjectId CreateDefaultTableStyle(Database db, Transaction tr)
{
try
{
// 获取表格样式字典
DBDictionary styleDict = (DBDictionary)tr.GetObject(db.TableStyleDictionaryId, OpenMode.ForWrite);
// 创建新的表格样式
TableStyle tableStyle = new TableStyle();
tableStyle.Name = "Standard";
// 设置标题样式
tableStyle.TitleCellStyle.TextHeight = 5;
tableStyle.TitleCellStyle.Alignment = CellAlignment.MiddleCenter;
tableStyle.TitleCellStyle.BackgroundColor = Color.FromColorIndex(ColorMethod.ByAci, 1);
// 设置表头样式
tableStyle.HeaderCellStyle.TextHeight = 4;
tableStyle.HeaderCellStyle.Alignment = CellAlignment.MiddleCenter;
tableStyle.HeaderCellStyle.BackgroundColor = Color.FromColorIndex(ColorMethod.ByAci, 5);
// 设置数据单元样式
tableStyle.DataCellStyle.TextHeight = 3.5;
tableStyle.DataCellStyle.Alignment = CellAlignment.MiddleCenter;
// 添加到字典
styleDict.SetAt("Standard", tableStyle);
tr.AddNewlyCreatedDBObject(tableStyle, true);
return tableStyle.ObjectId;
}
catch
{
// 如果创建失败,返回默认样式
return db.Tablestyle;
}
}
// ================== 辅助方法 ==================
// 增强轴号识别
private bool IsAxisNumber(string text)
{
if (string.IsNullOrWhiteSpace(text))
return false;
// 支持字母开头的轴号(如"A1", "B2")
if (Regex.IsMatch(text, @"^[A-Za-z]\d+$"))
return true;
// 支持纯数字轴号
if (Regex.IsMatch(text, @"^\d+$"))
return true;
// 支持带连字符的轴号(如"A-1", "1-A")
if (Regex.IsMatch(text, @"^[A-Za-z]-\d+$") ||
Regex.IsMatch(text, @"^\d+-[A-Za-z]$"))
return true;
// 支持包含"轴"字的文本(如"1轴", "A轴")
if (Regex.IsMatch(text, @"\d+轴") || Regex.IsMatch(text, @"[A-Za-z]轴"))
return true;
// 支持分数格式轴号(如"1/2")
if (Regex.IsMatch(text, @"^\d+/\d+$"))
return true;
return false;
}
// 增强梁标签识别
private bool IsBeamLabel(string text)
{
if (string.IsNullOrWhiteSpace(text))
return false;
// 支持常见梁标签格式(如"KL1", "L2", "B3"等)
if (Regex.IsMatch(text, @"^[Kk]?[LlBb]\d+"))
return true;
// 支持带括号的梁标签(如"Lg30(1)")
if (Regex.IsMatch(text, @"[Ll][Gg]?\d+$\d+$"))
return true;
// 支持集中标注格式(如"4-Lg30(1)"")
if (Regex.IsMatch(text, @"\d+-[Ll][Gg]?\d+$\d+$"))
return true;
// 支持梁编号前缀(如"梁L1", "KL-2")
if (Regex.IsMatch(text, @"[梁梁][-]?[Ll]\d+") ||
Regex.IsMatch(text, @"[Kk][Ll][-]?\d+"))
return true;
return false;
}
// 增强尺寸提取
private Match ExtractSizeFromBeamLabel(string label)
{
// 增强匹配模式:支持空格、不同分隔符
Regex sizePattern = new Regex(@"(\d{3,4})\s*[xX×]\s*(\d{3,4})");
return sizePattern.Match(label);
}
private bool IsBeamDimension(string text)
{
return !string.IsNullOrWhiteSpace(text) &&
Regex.IsMatch(text, @"\d{2,4}\s*[×xX]\s*\d{2,4}");
}
private bool IsPureBeamDimension(string text)
{
return !string.IsNullOrWhiteSpace(text) &&
Regex.IsMatch(text, @"^\d{2,4}\s*[×xX]\s*\d{2,4}$");
}
private bool IsBeamEntity(Entity ent)
{
return ent is Line || ent is Polyline;
}
private void AddSizeToDictionary(Dictionary<string, int> dict, string size)
{
if (dict.ContainsKey(size))
{
dict[size]++;
}
else
{
dict[size] = 1;
}
}
private List<BeamSizeInfo> CreateSortedBeamInfo(Dictionary<string, int> sizeCounts)
{
List<BeamSizeInfo> beamInfoList = new List<BeamSizeInfo>();
foreach (var kvp in sizeCounts)
{
string size = kvp.Key;
int count = kvp.Value;
// 解析尺寸
string[] dimensions = size.Split('x');
if (dimensions.Length != 2) continue;
if (!double.TryParse(dimensions[0], out double width)) continue;
if (!double.TryParse(dimensions[1], out double height)) continue;
// 计算截面面积 (mm² → m²)
double area = (width * height) / 1_000_000.0;
// 计算线荷载
double lineLoad = area * ConcreteDensity;
beamInfoList.Add(new BeamSizeInfo
{
Size = size,
Count = count,
Width = width,
Height = height,
Area = area,
LineLoad = lineLoad
});
}
// 按线荷载值降序排序(最大值排在最前)
return beamInfoList.OrderByDescending(b => b.LineLoad).ToList();
}
}
CS1061“TableStyle”未包含”TitleCellStyle”的定义,并且找不到可接受第一个“TableStyle”类型参数的可访问扩展方法“TitleCellStyle”(是否缺少using 指令或程序集引用?)
CS1061“TableStyle”未包含”TitleCellStyle”的定义,并且找不到可接受第一个“TableStyle”类型参数的可访问扩展方法“TitleCellStyle”(是否缺少using 指令或程序集引用?)
CS1061“TableStyle"未包含"TitleCellStyle”的定义,并且找不到可接受第一个“TableStyle"类型参数的可访问扩展方法"TitleCellStyle”(是否缺少using 指令或程序集引用?)
CS1061“TableStyle"未包含”HeaderCellStyle”的定义,并且找不到可接受第一个“TableStyle"类型参数的可访问扩展方法”HeaderCellStyle"(是否缺少using 指令或程序集引用?)
CS1061“TableStyle”未包含“HeaderCellStyle”的定义,并且找不到可接受第一个"TableStyle"类型参数的可访问扩展方法”HeaderCellStyle"(是否缺少using 指令或程序集引用?)
CS1061“TableStyle"未包含“HeaderCellStyle”的定义,并且找不到可接受第一个“TableStyle"类型参数的可访问扩展方法”HeaderCellStyle"(是否缺少using 指令或程序集引用?)
CS1061“TableStyle"未包含"DataCellStyle”的定义,并且找不到可接受第一个“TableStyle”类型参数的可访问扩展方法“DataCellStyle”(是否缺少using 指令或程序集引用?)
CS1061“TableStyle”未包含”DataCellStyle”的定义,并且找不到可接受第一个“TableStyle"类型参数的可访问扩展方法“DataCellStyle”(是否缺少using 指令或程序集引用?)