using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.Windows; // AutoCAD 专用对话框
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Forms; // 用于 DialogResult 枚举
using static Autodesk.AutoCAD.LayerManager.LayerFilter;
[assembly: CommandClass(typeof(ArchitectureCADPlugin.Commands))]
[assembly: CommandClass(typeof(ArchitectureCADPlugin.Loader))]
namespace ArchitectureCADPlugin
{
public class Commands
{
// 存储识别的图层名称
private static string axisLayer = "";
private static string axisNumberLayer = "";
private static string dimensionLayer = "";
private static string beamLayer = "";
private static string columnLayer = "";
private static string wallLayer = "";
private static string cavityLayer = "";
// 存储识别的梁信息
private static Dictionary<string, BeamInfo> beamInfoDict = new Dictionary<string, BeamInfo>();
// AXISID -> AID
[CommandMethod("AID", CommandFlags.Modal)]
public void IdentifyAxis()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
// 点选识别轴网、轴号及标注尺寸图层
ed.WriteMessage("\n【轴网识别】请点选轴网图层中的对象: ");
PromptEntityOptions peoAxis = new PromptEntityOptions("\n选择轴网对象: ");
peoAxis.SetRejectMessage("\n请选择轴网对象!");
peoAxis.AddAllowedClass(typeof(Entity), true);
PromptEntityResult perAxis = ed.GetEntity(peoAxis);
if (perAxis.Status != PromptStatus.OK) return;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity entAxis = tr.GetObject(perAxis.ObjectId, OpenMode.ForRead) as Entity;
if (entAxis != null)
{
axisLayer = entAxis.Layer;
ed.WriteMessage("\n已识别轴网图层: " + axisLayer);
}
ed.WriteMessage("\n【轴网识别】请点选轴号图层中的对象: ");
PromptEntityOptions peoAxisNum = new PromptEntityOptions("\n选择轴号对象: ");
peoAxisNum.SetRejectMessage("\n请选择轴号对象!");
peoAxisNum.AddAllowedClass(typeof(Entity), true);
PromptEntityResult perAxisNum = ed.GetEntity(peoAxisNum);
if (perAxisNum.Status == PromptStatus.OK)
{
Entity entAxisNum = tr.GetObject(perAxisNum.ObjectId, OpenMode.ForRead) as Entity;
if (entAxisNum != null)
{
axisNumberLayer = entAxisNum.Layer;
ed.WriteMessage("\n已识别轴号图层: " + axisNumberLayer);
}
}
ed.WriteMessage("\n【轴网识别】请点选标注尺寸图层中的对象: ");
PromptEntityOptions peoDim = new PromptEntityOptions("\n选择标注尺寸对象: ");
peoDim.SetRejectMessage("\n请选择标注尺寸对象!");
peoDim.AddAllowedClass(typeof(Entity), true);
PromptEntityResult perDim = ed.GetEntity(peoDim);
if (perDim.Status == PromptStatus.OK)
{
Entity entDim = tr.GetObject(perDim.ObjectId, OpenMode.ForRead) as Entity;
if (entDim != null)
{
dimensionLayer = entDim.Layer;
ed.WriteMessage("\n已识别标注尺寸图层: " + dimensionLayer);
}
}
ed.WriteMessage("\n【轴网识别】请框选所有图层: ");
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\n选择对象: ";
PromptSelectionResult psr = ed.GetSelection(pso);
if (psr.Status == PromptStatus.OK)
{
SelectionSet ss = psr.Value;
foreach (ObjectId objId in ss.GetObjectIds())
{
Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;
if (ent != null)
{
if (ent.Layer == axisLayer)
ed.WriteMessage("\n找到轴网对象: " + ent.GetType().Name);
else if (ent.Layer == axisNumberLayer)
ed.WriteMessage("\n找到轴号对象: " + ent.GetType().Name);
else if (ent.Layer == dimensionLayer)
ed.WriteMessage("\n找到标注尺寸对象: " + ent.GetType().Name);
}
}
}
tr.Commit();
}
SaveLayerSettings();
}
// BEAMSTAT -> BST
[CommandMethod("BST", CommandFlags.Modal)]
public void BeamStatistics()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
if (string.IsNullOrEmpty(beamLayer))
{
ed.WriteMessage("\n【梁统计】请先使用 BID 命令识别梁线图层!");
return;
}
ed.WriteMessage("\n【梁统计】请框选所有图层: ");
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.MessageForAdding = "\n选择对象: ";
PromptSelectionResult psr = ed.GetSelection(pso);
if (psr.Status != PromptStatus.OK) return;
Dictionary<string, int> beamCountDict = new Dictionary<string, int>();
Dictionary<string, int> sectionCountDict = new Dictionary<string, int>();
using (Transaction tr = db.TransactionManager.StartTransaction())
{
SelectionSet ss = psr.Value;
foreach (ObjectId objId in ss.GetObjectIds())
{
Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity;
if (ent != null && ent.Layer == beamLayer)
{
string beamName = ExtractBeamName(ent);
string sectionSize = ExtractSectionSize(ent);
if (!string.IsNullOrEmpty(beamName))
{
if (beamCountDict.ContainsKey(beamName))
beamCountDict[beamName]++;
else
beamCountDict.Add(beamName, 1);
}
else if (!string.IsNullOrEmpty(sectionSize))
{
if (sectionCountDict.ContainsKey(sectionSize))
sectionCountDict[sectionSize]++;
else
sectionCountDict.Add(sectionSize, 1);
}
}
}
CreateBeamStatisticsTable(beamCountDict, sectionCountDict, tr);
tr.Commit();
}
}
// BEAMID -> BID
[CommandMethod("BID", CommandFlags.Modal)]
public void IdentifyBeamLayer()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ed.WriteMessage("\n【梁识别】请点选梁线图层中的对象: ");
PromptEntityOptions peo = new PromptEntityOptions("\n选择梁线对象: ");
peo.SetRejectMessage("\n请选择梁线对象!");
peo.AddAllowedClass(typeof(Entity), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
if (ent != null)
{
beamLayer = ent.Layer;
ed.WriteMessage("\n已识别梁线图层: " + beamLayer);
SaveLayerSettings();
}
tr.Commit();
}
}
}
// COLUMNID -> CID
[CommandMethod("CID", CommandFlags.Modal)]
public void IdentifyColumnLayer()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ed.WriteMessage("\n【柱识别】请点选柱图层中的对象: ");
PromptEntityOptions peo = new PromptEntityOptions("\n选择柱对象: ");
peo.SetRejectMessage("\n请选择柱对象!");
peo.AddAllowedClass(typeof(Entity), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
if (ent != null)
{
columnLayer = ent.Layer;
ed.WriteMessage("\n已识别柱图层: " + columnLayer);
SaveLayerSettings();
}
tr.Commit();
}
}
}
// WALLID -> WID
[CommandMethod("WID", CommandFlags.Modal)]
public void IdentifyWallLayer()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
ed.WriteMessage("\n【墙识别】请点选墙图层中的对象: ");
PromptEntityOptions peo = new PromptEntityOptions("\n选择墙对象: ");
peo.SetRejectMessage("\n请选择墙对象!");
peo.AddAllowedClass(typeof(Entity), true);
PromptEntityResult per = ed.GetEntity(peo);
if (per.Status == PromptStatus.OK)
{
using (Transaction tr = db.TransactionManager.StartTransaction())
{
Entity ent = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Entity;
if (ent != null)
{
wallLayer = ent.Layer;
ed.WriteMessage("\n已识别墙图层: " + wallLayer);
SaveLayerSettings();
}
tr.Commit();
}
}
}
// EXPORTBEAM -> EB
[CommandMethod("EB", CommandFlags.Modal)]
public void ExportBeamToExcel()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
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;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
SelectionSet ss = psr.Value;
if (ss.Count == 1)
{
ObjectId tableId = ss.GetObjectIds()[0];
Table table = tr.GetObject(tableId, OpenMode.ForRead) as Table;
if (table != null)
{
ExportTableToCSV(table);
}
}
tr.Commit();
}
}
// LOADSETTINGS -> LS
[CommandMethod("LS", CommandFlags.Modal)]
public void LoadLayerSettings()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
axisLayer = Application.GetSystemVariable("AXIS_LAYER").ToString();
axisNumberLayer = Application.GetSystemVariable("AXIS_NUM_LAYER").ToString();
dimensionLayer = Application.GetSystemVariable("DIM_LAYER").ToString();
beamLayer = Application.GetSystemVariable("BEAM_LAYER").ToString();
columnLayer = Application.GetSystemVariable("COLUMN_LAYER").ToString();
wallLayer = Application.GetSystemVariable("WALL_LAYER").ToString();
cavityLayer = Application.GetSystemVariable("CAVITY_LAYER").ToString();
ed.WriteMessage("\n已加载图层设置:");
ed.WriteMessage("\n轴网图层: " + axisLayer);
ed.WriteMessage("\n轴号图层: " + axisNumberLayer);
ed.WriteMessage("\n标注尺寸图层: " + dimensionLayer);
ed.WriteMessage("\n梁线图层: " + beamLayer);
ed.WriteMessage("\n柱图层: " + columnLayer);
ed.WriteMessage("\n墙图层: " + wallLayer);
}
// SHOWSETTINGS -> SS
[CommandMethod("SS", CommandFlags.Modal)]
public void ShowLayerSettings()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor ed = doc.Editor;
ed.WriteMessage("\n当前图层设置:");
ed.WriteMessage("\n轴网图层: " + axisLayer);
ed.WriteMessage("\n轴号图层: " + axisNumberLayer);
ed.WriteMessage("\n标注尺寸图层: " + dimensionLayer);
ed.WriteMessage("\n梁线图层: " + beamLayer);
ed.WriteMessage("\n柱图层: " + columnLayer);
ed.WriteMessage("\n墙图层: " + wallLayer);
ed.WriteMessage("\n空洞图层: " + cavityLayer);
}
private void SaveLayerSettings()
{
Application.SetSystemVariable("AXIS_LAYER", axisLayer);
Application.SetSystemVariable("AXIS_NUM_LAYER", axisNumberLayer);
Application.SetSystemVariable("DIM_LAYER", dimensionLayer);
Application.SetSystemVariable("BEAM_LAYER", beamLayer);
Application.SetSystemVariable("COLUMN_LAYER", columnLayer);
Application.SetSystemVariable("WALL_LAYER", wallLayer);
Application.SetSystemVariable("CAVITY_LAYER", cavityLayer);
}
private string ExtractBeamName(Entity ent)
{
// 示例实现 - 实际应根据项目需求完善
if (ent is DBText text)
return text.TextString;
return string.Empty;
}
private string ExtractSectionSize(Entity ent)
{
// 示例实现 - 实际应根据项目需求完善
if (ent is MText mtext)
return mtext.Text;
if (ent is DBText text)
return text.TextString;
return string.Empty;
}
private void CreateBeamStatisticsTable(Dictionary<string, int> beamCountDict,
Dictionary<string, int> sectionCountDict,
Transaction tr)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
PromptPointOptions ppo = new PromptPointOptions("\n【梁统计】请指定表格插入点: ");
PromptPointResult ppr = ed.GetPoint(ppo);
if (ppr.Status != PromptStatus.OK) return;
Point3d insertPoint = ppr.Value;
List<BeamStatItem> statItems = new List<BeamStatItem>();
foreach (var pair in beamCountDict)
{
BeamInfo beamInfo = null;
if (beamInfoDict.TryGetValue(pair.Key, out beamInfo))
{
statItems.Add(new BeamStatItem
{
Name = pair.Key,
SectionSize = beamInfo.SectionSize,
Count = pair.Value
});
}
else
{
// 如果梁信息字典中没有对应的梁信息,添加一个默认项
statItems.Add(new BeamStatItem
{
Name = pair.Key,
SectionSize = "未知尺寸",
Count = pair.Value
});
}
}
foreach (var pair in sectionCountDict)
{
statItems.Add(new BeamStatItem
{
Name = "",
SectionSize = pair.Key,
Count = pair.Value
});
}
foreach (var item in statItems)
{
if (item.SectionSize != "未知尺寸")
{
string sizeText = item.SectionSize.Replace("x", "*");
string[] parts = sizeText.Split('*');
if (parts.Length == 2 && double.TryParse(parts[0], out double width) && double.TryParse(parts[1], out double height))
{
item.Area = width * height / 1000000;
item.Load = item.Area * 25;
}
}
}
statItems = statItems.OrderByDescending(i => i.Load).ToList();
Table table = new Table();
table.SetDatabaseDefaults();
table.TableStyle = db.Tablestyle;
table.Position = insertPoint;
// 设置行数和列数
int rowCount = 2 + statItems.Count;
int colCount = 6;
table.SetSize(rowCount, colCount);
// 设置列宽
for (int i = 0; i < colCount; i++)
{
switch (i)
{
case 0: table.Columns[i].Width = 100; break;
case 1: table.Columns[i].Width = 200; break;
case 2: table.Columns[i].Width = 150; break;
case 3: table.Columns[i].Width = 100; break;
case 4: table.Columns[i].Width = 150; break;
case 5: table.Columns[i].Width = 150; break;
}
}
// 设置标题行
table.Cells[0, 0].Value = "梁截面尺寸汇总表";
table.Cells[0, 0].Alignment = CellAlignment.MiddleCenter;
table.Cells[0, 0].TextHeight = 50;
table.MergeCells(CellRange.Create(table, 0, 0, 0, colCount - 1));
// 设置表头
string[] headers = { "序号", "梁名称", "梁截面尺寸mm", "数量", "截面面积㎡", "集中线荷载(KN/m)" };
for (int i = 0; i < headers.Length; i++)
{
table.Cells[1, i].Value = headers[i];
table.Cells[1, i].Alignment = CellAlignment.MiddleCenter;
table.Cells[1, i].TextHeight = 35;
}
// 添加数据行
for (int i = 0; i < statItems.Count; i++)
{
var item = statItems[i];
table.Cells[2 + i, 0].Value = (i + 1).ToString();
table.Cells[2 + i, 1].Value = item.Name;
table.Cells[2 + i, 2].Value = item.SectionSize;
table.Cells[2 + i, 3].Value = item.Count.ToString();
table.Cells[2 + i, 4].Value = item.Area.ToString("F6");
table.Cells[2 + i, 5].Value = item.Load.ToString("F2");
for (int j = 0; j < headers.Length; j++)
{
table.Cells[2 + i, j].Alignment = CellAlignment.MiddleCenter;
table.Cells[2 + i, j].TextHeight = 30;
}
}
BlockTableRecord btr = (BlockTableRecord)tr.GetObject(
doc.Database.CurrentSpaceId, OpenMode.ForWrite);
btr.AppendEntity(table);
tr.AddNewlyCreatedDBObject(table, true);
ed.WriteMessage("\n【梁统计】已生成梁统计表格");
}
private void ExportTableToCSV(Table table)
{
try
{
// 创建保存文件对话框
SaveFileDialog saveDlg = new SaveFileDialog(
"【梁统计】保存梁统计表格", // 对话框标题
"梁截面尺寸汇总表.csv", // 默认文件名
"csv", // 默认扩展名
"CSV文件|*.csv" // 文件过滤器
);
// 显示对话框
DialogResult result = saveDlg.ShowDialog();
if (result != DialogResult.OK)
return;
string filePath = saveDlg.FileName;
// 确保文件扩展名正确
if (!filePath.EndsWith(".csv", StringComparison.OrdinalIgnoreCase))
{
filePath += ".csv";
}
// 创建CSV内容
StringBuilder csvContent = new StringBuilder();
csvContent.AppendLine("序号,梁名称,梁截面尺寸mm,数量,截面面积㎡,集中线荷载(KN/m)");
// 添加数据行(跳过标题行)
for (int row = 2; row < table.Rows.Count; row++)
{
List<string> rowData = new List<string>();
for (int col = 0; col < table.Columns.Count; col++)
{
if (table.Cells[row, col] != null)
{
string value = table.Cells[row, col].Value?.ToString() ?? "";
// 处理可能包含逗号的内容
if (value.Contains(","))
value = "\"" + value + "\"";
rowData.Add(value);
}
}
csvContent.AppendLine(string.Join(",", rowData));
}
// 写入文件
File.WriteAllText(filePath, csvContent.ToString(), Encoding.UTF8);
Application.ShowAlertDialog("表格已成功导出到:\n" + filePath);
}
catch (Exception ex)
{
Application.ShowAlertDialog("导出CSV时出错:\n" + ex.Message);
}
}
}
public class BeamInfo
{
public string Name { get; set; }
public string SectionSize { get; set; }
public string Elevation { get; set; }
}
public class BeamStatItem
{
public string Name { get; set; }
public string SectionSize { get; set; }
public int Count { get; set; }
public double Area { get; set; }
public double Load { get; set; }
}
public class Loader
{
[CommandMethod("LOADARCHPLUGIN", CommandFlags.Modal)]
public void LoadPlugin()
{
Application.ShowAlertDialog("建筑CAD识别与标注插件已加载!");
}
}
}
以上代码出现以下5个问题:CS0234命名空间“System.Windows”中不存在类型或命名空间名“Forms”(是否缺少程序集引用?)
CS7036未提供与“SaveFileDialog.SaveFileDialog(string,string,string,string, SaveFileDialog.SaveFileDialogFlags)”的所需参数“flags"对应的参数
CS0012类型"DialogResult”在未引用的程序集中定义。必须添加对程序集"System.Windows.Forms,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089"的引用。
CS1061“SaveFileDialog”未包含”FileName”的定义,并且找不到可接受第一个“SaveFileDialog”类型参数的可访问扩展方法“FileName”(是否缺少using指令或程序集引用?)
CS0104“Exception”是Autodesk.AutoCAD.Runtime.Exception”和System.Exception”之间的不明确的引用
最新发布