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.IO;
using System.Linq;
using System.Reflection;
namespace ScaffoldAutomation
{
public class DiagonalBarPlacer
{
// 配置常量
private const string DiagonalBarLayer = “斜拉杆”;
private const string DiagonalBarPrefix = “ScaffoldPolexie水平斜拉杆”;
private const string BlockDirectoryName = “ScaffoldBlocks”;
private const string AxisLayer = “盘扣轴网”;
// 标准斜拉杆长度(毫米) private static readonly double[] DiagonalBarLengths = { 600, 900, 1200, 1500, 1800 }; // 缓存已存在的斜拉杆 private readonly Dictionary<string, HashSet<string>> _existingDiagonalCache = new Dictionary<string, HashSet<string>>(); // 插件目录路径 private readonly string _pluginDirectory; // 网格数据结构 private GridStructure _grid; // 容差值(毫米) private const double Tolerance = 1.0; // 1mm容差 public DiagonalBarPlacer() { _pluginDirectory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location); } [CommandMethod("BuildDiagonal", "BD", CommandFlags.Modal)] public void BuildDiagonal() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { // 创建斜杆图层 CreateLayerIfNotExists(db, DiagonalBarLayer, 4); // 青色 CheckLayerState(db, DiagonalBarLayer); // 步骤1:选择布置模式 int mode = GetDiagonalMode(ed); if (mode == 0) return; // 步骤2:选择轴网线段 PromptSelectionOptions selOpts = new PromptSelectionOptions(); selOpts.MessageForAdding = "\n选择盘扣轴网线段: "; PromptSelectionResult selResult = ed.GetSelection(selOpts); if (selResult.Status != PromptStatus.OK) return; // 加载斜拉杆块定义 LoadDiagonalBlockDefinitions(db, ed); // 构建现有斜拉杆缓存 BuildExistingDiagonalCache(db); using (Transaction tr = db.TransactionManager.StartTransaction()) { // 处理轴网并生成网格结构 if (!ProcessAxisLines(db, selResult, tr, ed)) { ed.WriteMessage("\n无法生成有效的网格结构"); return; } // 布置斜拉杆 int diagonalCount = PlaceDiagonalBars(db, tr, mode, ed); tr.Commit(); ed.WriteMessage($"\n成功布置 {diagonalCount} 根斜拉杆"); if (diagonalCount > 0) { Application.ShowAlertDialog($"已布置 {diagonalCount} 根斜拉杆!"); } } } catch (System.Exception ex) { ed.WriteMessage($"\n错误: {ex.Message}"); } } #region 网格数据结构 // 网格结构 private class GridStructure { public List<double> XCoordinates { get; set; } = new List<double>(); public List<double> YCoordinates { get; set; } = new List<double>(); public List<GridEdge> HorizontalEdges { get; } = new List<GridEdge>(); public List<GridEdge> VerticalEdges { get; } = new List<GridEdge>(); public int RowCount => YCoordinates.Count - 1; public int ColumnCount => XCoordinates.Count - 1; } // 网格边 private class GridEdge { public Point3d StartPoint { get; set; } public Point3d EndPoint { get; set; } public double Length { get; set; } public int RowIndex { get; set; } // 行索引(水平边) public int ColIndex { get; set; } // 列索引(垂直边) public bool IsHorizontal { get; set; } public bool IsOuterEdge { get; set; } // 是否是最外侧边 public bool IsTopEdge { get; set; } // 是否是顶部边 public bool IsBottomEdge { get; set; } // 是否是底部边 public bool IsLeftEdge { get; set; } // 是否是左侧边 public bool IsRightEdge { get; set; } // 是否是右侧边 } // 点比较器(用于去重) private class Point3dComparer : IEqualityComparer<Point3d> { private readonly double _tolerance; public Point3dComparer(double tolerance) { _tolerance = tolerance; } public bool Equals(Point3d p1, Point3d p2) { return p1.DistanceTo(p2) <= _tolerance; } public int GetHashCode(Point3d p) { return (Math.Round(p.X / _tolerance), Math.Round(p.Y / _tolerance), Math.Round(p.Z / _tolerance)).GetHashCode(); } } #endregion #region 轴网处理 // 处理轴网线段 private bool ProcessAxisLines(Database db, PromptSelectionResult selResult, Transaction tr, Editor ed) { List<Line> axisLines = new List<Line>(); // 收集轴网线段 foreach (ObjectId objId in selResult.Value.GetObjectIds()) { Entity ent = tr.GetObject(objId, OpenMode.ForRead) as Entity; if (ent != null && ent.Layer == AxisLayer && ent is Line line) { axisLines.Add(line); } } if (axisLines.Count == 0) { ed.WriteMessage("\n未选择任何轴网线段"); return false; } ed.WriteMessage($"\n找到 {axisLines.Count} 条轴网线段"); // 计算所有网格交点 List<Point3d> intersections = CalculateIntersections(axisLines, ed); if (intersections.Count == 0) { ed.WriteMessage("\n未找到网格交点"); return false; } // 构建网格结构 _grid = BuildGridStructure(intersections, axisLines, ed); if (_grid == null || _grid.XCoordinates.Count < 2 || _grid.YCoordinates.Count < 2) { ed.WriteMessage("\n无法构建有效的网格结构"); return false; } ed.WriteMessage($"\n网格结构: {_grid.ColumnCount}列 x {_grid.RowCount}行"); ed.WriteMessage($"\n水平边数量: {_grid.HorizontalEdges.Count}, 垂直边数量: {_grid.VerticalEdges.Count}"); return true; } // 计算所有网格交点 private List<Point3d> CalculateIntersections(List<Line> axisLines, Editor ed) { var intersections = new HashSet<Point3d>(new Point3dComparer(Tolerance)); int totalIntersections = 0; // 计算所有线段的交点 for (int i = 0; i < axisLines.Count; i++) { for (int j = i + 1; j < axisLines.Count; j++) { Point3dCollection pts = new Point3dCollection(); axisLines[i].IntersectWith( axisLines[j], Intersect.ExtendBoth, pts, IntPtr.Zero, IntPtr.Zero ); foreach (Point3d pt in pts) { intersections.Add(RoundPoint(pt, Tolerance)); totalIntersections++; } } } ed.WriteMessage($"\n找到 {intersections.Count} 个有效网格交点(总交点: {totalIntersections})"); return intersections.ToList(); } // 构建网格结构 private GridStructure BuildGridStructure(List<Point3d> intersections, List<Line> axisLines, Editor ed) { var grid = new GridStructure(); // 分离X和Y坐标(带容差) var xCoords = new List<double>(); var yCoords = new List<double>(); // 使用容差分组坐标 var xGroups = intersections.GroupBy(p => Math.Round(p.X / Tolerance) * Tolerance); var yGroups = intersections.GroupBy(p => Math.Round(p.Y / Tolerance) * Tolerance); // 获取排序后的坐标 xCoords = xGroups.Select(g => g.Key).OrderBy(x => x).ToList(); yCoords = yGroups.Select(g => g.Key).OrderBy(y => y).ToList(); grid.XCoordinates = xCoords; grid.YCoordinates = yCoords; // 创建水平边 for (int row = 0; row < yCoords.Count; row++) { for (int col = 0; col < xCoords.Count - 1; col++) { Point3d start = new Point3d(xCoords[col], yCoords[row], 0); Point3d end = new Point3d(xCoords[col + 1], yCoords[row], 0); // 检查是否为有效线段 if (IsValidSegment(axisLines, start, end, Tolerance)) { grid.HorizontalEdges.Add(new GridEdge { StartPoint = start, EndPoint = end, Length = start.DistanceTo(end), RowIndex = row, ColIndex = col, IsHorizontal = true, IsOuterEdge = (row == 0 || row == yCoords.Count - 1), IsTopEdge = (row == 0), IsBottomEdge = (row == yCoords.Count - 1) }); } } } // 创建垂直边 for (int col = 0; col < xCoords.Count; col++) { for (int row = 0; row < yCoords.Count - 1; row++) { Point3d start = new Point3d(xCoords[col], yCoords[row], 0); Point3d end = new Point3d(xCoords[col], yCoords[row + 1], 0); // 检查是否为有效线段 if (IsValidSegment(axisLines, start, end, Tolerance)) { grid.VerticalEdges.Add(new GridEdge { StartPoint = start, EndPoint = end, Length = start.DistanceTo(end), RowIndex = row, ColIndex = col, IsHorizontal = false, IsOuterEdge = (col == 0 || col == xCoords.Count - 1), IsLeftEdge = (col == 0), IsRightEdge = (col == xCoords.Count - 1) }); } } } return grid; } // 检查点是否在直线上(带容差) private bool IsPointOnLine(Line line, Point3d point, double tolerance) { // 检查点是否接近起点或终点 if (point.DistanceTo(line.StartPoint) <= tolerance || point.DistanceTo(line.EndPoint) <= tolerance) return true; // 计算点到直线的距离 Vector3d lineVec = line.EndPoint - line.StartPoint; Vector3d pointVec = point - line.StartPoint; // 检查点是否在线段范围内 double dotProduct = lineVec.DotProduct(pointVec); if (dotProduct < 0 || dotProduct > lineVec.LengthSqrd) return false; // 计算垂直距离 double distance = Math.Abs(lineVec.CrossProduct(pointVec).Length / lineVec.Length); return distance <= tolerance; } // 检查是否为有效线段(带容差) private bool IsValidSegment(List<Line> axisLines, Point3d start, Point3d end, double tolerance) { foreach (Line line in axisLines) { if (IsPointOnLine(line, start, tolerance) && IsPointOnLine(line, end, tolerance)) { return true; } } return false; } #endregion #region 斜拉杆布置核心逻辑(按模式实现) // 布置斜拉杆(根据不同的布置模式) private int PlaceDiagonalBars(Database db, Transaction tr, int mode, Editor ed) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); if (_grid == null || (_grid.HorizontalEdges.Count == 0 && _grid.VerticalEdges.Count == 0)) { ed.WriteMessage("\n没有可用的网格边"); return 0; } int diagonalCount = 0; var placedEdges = new HashSet<string>(); // 避免重复布置 // 模式1: 隔一布一 if (mode == 1) { diagonalCount += PlacePatternOne(db, tr, btr, bt, placedEdges, ed); } // 模式2: 隔二布一 else if (mode == 2) { diagonalCount += PlacePatternTwo(db, tr, btr, bt, placedEdges, ed); } // 模式3: 隔三布一 else if (mode == 3) { diagonalCount += PlacePatternThree(db, tr, btr, bt, placedEdges, ed); } // 模式4: 满布 else if (mode == 4) { diagonalCount += PlaceFullPattern(db, tr, btr, bt, placedEdges, ed); } return diagonalCount; } // 模式1: 隔一布一 private int PlacePatternOne(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed) { int count = 0; // 遍历所有网格单元 for (int row = 0; row < _grid.RowCount; row++) { for (int col = 0; col < _grid.ColumnCount; col++) { // 隔一布一:行和列索引都是偶数的单元 if (row % 2 == 0 && col % 2 == 0) { count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed); } } } ed.WriteMessage($"\n隔一布一模式: 布置了 {count} 根斜拉杆"); return count; } // 模式2: 隔二布一 private int PlacePatternTwo(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed) { int count = 0; // 布置所有单元(隔二布一) for (int row = 0; row < _grid.RowCount; row++) { for (int col = 0; col < _grid.ColumnCount; col++) { // 隔二布一:每3个单元布置一个(行和列索引都是3的倍数) if (row % 3 == 0 && col % 3 == 0) { count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed); } } } // 布置中间垂直边(隔二布一) for (int col = 1; col < _grid.ColumnCount; col += 3) // 中间列(每3列的第2列) { for (int row = 0; row < _grid.RowCount; row++) { var edge = _grid.VerticalEdges.FirstOrDefault(e => e.ColIndex == col && e.RowIndex == row); if (edge != null) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } } // 布置中间水平边(隔二布一) for (int row = 1; row < _grid.RowCount; row += 3) // 中间行(每3行的第2行) { for (int col = 0; col < _grid.ColumnCount; col++) { var edge = _grid.HorizontalEdges.FirstOrDefault(e => e.RowIndex == row && e.ColIndex == col); if (edge != null) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } } ed.WriteMessage($"\n隔二布一模式: 布置了 {count} 根斜拉杆"); return count; } // 模式3: 隔三布一 private int PlacePatternThree(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed) { int count = 0; // 布置所有单元(隔三布一) for (int row = 0; row < _grid.RowCount; row++) { for (int col = 0; col < _grid.ColumnCount; col++) { // 隔三布一:每4个单元布置一个(行和列索引都是4的倍数) if (row % 4 == 0 && col % 4 == 0) { count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed); } } } // 布置中间垂直边(隔三布一) for (int col = 1; col < _grid.ColumnCount; col += 4) // 每4列的第2列 { for (int row = 0; row < _grid.RowCount; row++) { var edge = _grid.VerticalEdges.FirstOrDefault(e => e.ColIndex == col && e.RowIndex == row); if (edge != null) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } } for (int col = 2; col < _grid.ColumnCount; col += 4) // 每4列的第3列 { for (int row = 0; row < _grid.RowCount; row++) { var edge = _grid.VerticalEdges.FirstOrDefault(e => e.ColIndex == col && e.RowIndex == row); if (edge != null) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } } // 布置中间水平边(隔三布一) for (int row = 1; row < _grid.RowCount; row += 4) // 每4行的第2行 { for (int col = 0; col < _grid.ColumnCount; col++) { var edge = _grid.HorizontalEdges.FirstOrDefault(e => e.RowIndex == row && e.ColIndex == col); if (edge != null) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } } for (int row = 2; row < _grid.RowCount; row += 4) // 每4行的第3行 { for (int col = 0; col < _grid.ColumnCount; col++) { var edge = _grid.HorizontalEdges.FirstOrDefault(e => e.RowIndex == row && e.ColIndex == col); if (edge != null) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } } ed.WriteMessage($"\n隔三布一模式: 布置了 {count} 根斜拉杆"); return count; } // 模式4: 满布 private int PlaceFullPattern(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed) { int count = 0; // 布置所有水平边 foreach (GridEdge edge in _grid.HorizontalEdges) { // 最外侧边特殊处理(布置在外侧) if (edge.IsOuterEdge) { count += PlaceOuterBar(edge, btr, bt, placedEdges, db, tr, ed); } else { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } // 布置所有垂直边 foreach (GridEdge edge in _grid.VerticalEdges) { // 最外侧边特殊处理(布置在外侧) if (edge.IsOuterEdge) { count += PlaceOuterBar(edge, btr, bt, placedEdges, db, tr, ed); } else { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed); } } ed.WriteMessage($"\n满布模式: 布置了 {count} 根斜拉杆"); return count; } // 布置单个网格单元的四条边 private int PlaceCellEdges(int row, int col, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Database db, Transaction tr, Editor ed) { int count = 0; // 上边 var topEdge = _grid.HorizontalEdges.FirstOrDefault(e => e.RowIndex == row && e.ColIndex == col); if (topEdge != null) { count += PlaceSingleBar(topEdge, btr, bt, placedEdges, db, tr, ed); } // 下边 var bottomEdge = _grid.HorizontalEdges.FirstOrDefault(e => e.RowIndex == row + 1 && e.ColIndex == col); if (bottomEdge != null) { count += PlaceSingleBar(bottomEdge, btr, bt, placedEdges, db, tr, ed); } // 左边 var leftEdge = _grid.VerticalEdges.FirstOrDefault(e => e.ColIndex == col && e.RowIndex == row); if (leftEdge != null) { count += PlaceSingleBar(leftEdge, btr, bt, placedEdges, db, tr, ed); } // 右边 var rightEdge = _grid.VerticalEdges.FirstOrDefault(e => e.ColIndex == col + 1 && e.RowIndex == row); if (rightEdge != null) { count += PlaceSingleBar(rightEdge, btr, bt, placedEdges, db, tr, ed); } return count; } // 布置单根斜拉杆(标准位置) private int PlaceSingleBar(GridEdge edge, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Database db, Transaction tr, Editor ed) { // 生成边唯一标识 string edgeKey = $"{edge.StartPoint.X:F3},{edge.StartPoint.Y:F3}-{edge.EndPoint.X:F3},{edge.EndPoint.Y:F3}"; // 检查是否已布置 if (placedEdges.Contains(edgeKey)) { return 0; } placedEdges.Add(edgeKey); // 获取最接近的标准长度 double closestLength = GetClosestDiagonalLength(edge.Length); // 检查长度匹配精度 if (Math.Abs(closestLength - edge.Length) > Tolerance) { ed.WriteMessage($"\n警告: 线段长度 {edge.Length:F0}mm 与标准长度 {closestLength}mm 不匹配 (差值: {Math.Abs(closestLength - edge.Length):F1}mm)"); return 0; } string blockName = $"{DiagonalBarPrefix}{closestLength:0}mm"; // 计算中点位置 Point3d midPoint = new Point3d( (edge.StartPoint.X + edge.EndPoint.X) / 2, (edge.StartPoint.Y + edge.EndPoint.Y) / 2, 0); // 计算旋转角度(考虑镜像方向) double rotation = 0.0; if (edge.IsHorizontal) { // 水平边:顶部0度,底部180度 rotation = edge.IsTopEdge ? 0.0 : Math.PI; } else { // 垂直边:左侧90度,右侧270度 rotation = edge.IsLeftEdge ? Math.PI / 2 : 3 * Math.PI / 2; } // 检查是否已存在相同斜拉杆 if (IsDiagonalAlreadyExists(blockName, midPoint, rotation)) { ed.WriteMessage($"\n跳过已存在斜拉杆: {blockName} 在 ({midPoint.X:F0},{midPoint.Y:F0})"); return 0; } // 动态加载块(如果未加载) if (!bt.Has(blockName)) { if (!LoadDiagonalBlock(db, closestLength, ed)) { return 0; } bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); } ObjectId blockId = bt[blockName]; // 创建斜杆图块引用 BlockReference br = new BlockReference(midPoint, blockId) { Layer = DiagonalBarLayer, Rotation = rotation }; // 添加到图形 btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // 添加到缓存 AddToDiagonalCache(blockName, midPoint, rotation); // 添加日志 ed.WriteMessage($"\n布置: {blockName} ({edge.Length:F0}mm) 在 ({midPoint.X:F0},{midPoint.Y:F0}), " + $"方向={(edge.IsHorizontal ? "水平" : "垂直")}, " + $"角度={rotation * 180 / Math.PI:F0}度"); return 1; } // 布置外侧斜拉杆(特殊处理) private int PlaceOuterBar(GridEdge edge, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Database db, Transaction tr, Editor ed) { // 生成边唯一标识 string edgeKey = $"{edge.StartPoint.X:F3},{edge.StartPoint.Y:F3}-{edge.EndPoint.X:F3},{edge.EndPoint.Y:F3}"; // 检查是否已布置 if (placedEdges.Contains(edgeKey)) { return 0; } placedEdges.Add(edgeKey); // 获取最接近的标准长度 double closestLength = GetClosestDiagonalLength(edge.Length); // 检查长度匹配精度 if (Math.Abs(closestLength - edge.Length) > Tolerance) { ed.WriteMessage($"\n警告: 线段长度 {edge.Length:F0}mm 与标准长度 {closestLength}mm 不匹配 (差值: {Math.Abs(closestLength - edge.Length):F1}mm)"); return 0; } string blockName = $"{DiagonalBarPrefix}{closestLength:0}mm"; // 计算中点位置 Point3d midPoint = new Point3d( (edge.StartPoint.X + edge.EndPoint.X) / 2, (edge.StartPoint.Y + edge.EndPoint.Y) / 2, 0); // 计算旋转角度(考虑镜像方向) double rotation = 0.0; if (edge.IsHorizontal) { // 水平边:顶部0度,底部180度 rotation = edge.IsTopEdge ? 0.0 : Math.PI; } else { // 垂直边:左侧90度,右侧270度 rotation = edge.IsLeftEdge ? Math.PI / 2 : 3 * Math.PI / 2; } // 外侧边特殊处理:向外偏移 double offsetDistance = 50; // 向外偏移50mm Vector3d offsetDirection = Vector3d.ZAxis; if (edge.IsHorizontal) { // 上边向下偏移,下边向上偏移 offsetDirection = edge.IsTopEdge ? new Vector3d(0, -offsetDistance, 0) : new Vector3d(0, offsetDistance, 0); } else { // 左边向右偏移,右边向左偏移 offsetDirection = edge.IsLeftEdge ? new Vector3d(offsetDistance, 0, 0) : new Vector3d(-offsetDistance, 0, 0); } midPoint += offsetDirection; // 检查是否已存在相同斜拉杆 if (IsDiagonalAlreadyExists(blockName, midPoint, rotation)) { ed.WriteMessage($"\n跳过已存在斜拉杆: {blockName} 在 ({midPoint.X:F0},{midPoint.Y:F0})"); return 0; } // 动态加载块(如果未加载) if (!bt.Has(blockName)) { if (!LoadDiagonalBlock(db, closestLength, ed)) { return 0; } bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); } ObjectId blockId = bt[blockName]; // 创建斜杆图块引用 BlockReference br = new BlockReference(midPoint, blockId) { Layer = DiagonalBarLayer, Rotation = rotation }; // 添加到图形 btr.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); // 添加到缓存 AddToDiagonalCache(blockName, midPoint, rotation); // 添加日志 ed.WriteMessage($"\n布置外侧: {blockName} ({edge.Length:F0}mm) 在 ({midPoint.X:F0},{midPoint.Y:F0}), " + $"方向={(edge.IsHorizontal ? "水平" : "垂直")}, " + $"角度={rotation * 180 / Math.PI:F0}度"); return 1; } // 获取最接近的标准长度 private double GetClosestDiagonalLength(double segmentLength) { // 精确匹配优先 foreach (double len in DiagonalBarLengths) { if (Math.Abs(len - segmentLength) < Tolerance) return len; } // 找不到精确匹配则返回最接近的 return DiagonalBarLengths .OrderBy(len => Math.Abs(len - segmentLength)) .First(); } #endregion #region 斜拉杆缓存管理 // 构建现有斜拉杆缓存 private void BuildExistingDiagonalCache(Database db) { _existingDiagonalCache.Clear(); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForRead); foreach (ObjectId objId in btr) { BlockReference br = tr.GetObject(objId, OpenMode.ForRead) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer) { string blockName = br.BlockName; Point3d roundedPos = RoundPoint(br.Position); double roundedAngle = Math.Round(br.Rotation, 4); AddToDiagonalCache(blockName, roundedPos, roundedAngle); } } tr.Commit(); } } // 添加斜拉杆到缓存 private void AddToDiagonalCache(string blockName, Point3d position, double angle) { string key = $"{position.X:F3},{position.Y:F3},{angle:F4}"; if (!_existingDiagonalCache.ContainsKey(blockName)) { _existingDiagonalCache[blockName] = new HashSet<string>(); } _existingDiagonalCache[blockName].Add(key); } // 检查斜拉杆是否已存在 private bool IsDiagonalAlreadyExists(string blockName, Point3d position, double angle) { Point3d roundedPos = RoundPoint(position); double roundedAngle = Math.Round(angle, 4); string key = $"{roundedPos.X:F3},{roundedPos.Y:F3},{roundedAngle:F4}"; return _existingDiagonalCache.ContainsKey(blockName) && _existingDiagonalCache[blockName].Contains(key); } // 四舍五入点坐标 private Point3d RoundPoint(Point3d point, double tolerance = Tolerance) { double roundFactor = 1.0 / tolerance; return new Point3d( Math.Round(point.X * roundFactor) / roundFactor, Math.Round(point.Y * roundFactor) / roundFactor, Math.Round(point.Z * roundFactor) / roundFactor); } #endregion #region 辅助方法 // 创建图层(如果不存在) private void CreateLayerIfNotExists(Database db, string layerName, int colorIndex) { using (Transaction tr = db.TransactionManager.StartTransaction()) { LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); if (!lt.Has(layerName)) { lt.UpgradeOpen(); LayerTableRecord ltr = new LayerTableRecord { Name = layerName, Color = Color.FromColorIndex(ColorMethod.ByAci, (short)colorIndex) }; lt.Add(ltr); tr.AddNewlyCreatedDBObject(ltr, true); } tr.Commit(); } } // 确保图层可见 private void CheckLayerState(Database db, string layerName) { using (Transaction tr = db.TransactionManager.StartTransaction()) { LayerTable lt = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); if (lt.Has(layerName)) { ObjectId layerId = lt[layerName]; LayerTableRecord ltr = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead); if (ltr.IsFrozen || ltr.IsOff) { ltr.UpgradeOpen(); ltr.IsFrozen = false; ltr.IsOff = false; } } tr.Commit(); } } // 获取布置模式 private int GetDiagonalMode(Editor ed) { PromptKeywordOptions pko = new PromptKeywordOptions("\n选择斜拉杆布置模式: "); pko.Keywords.Add("1", "1", "1. 隔一布一"); pko.Keywords.Add("2", "2", "2. 隔二布一"); pko.Keywords.Add("3", "3", "3. 隔三布一"); pko.Keywords.Add("4", "4", "4. 满布"); pko.AllowNone = false; pko.AppendKeywordsToMessage = true; PromptResult pr = ed.GetKeywords(pko); return pr.Status == PromptStatus.OK ? int.Parse(pr.StringResult) : 0; } // 加载斜拉杆块定义 private void LoadDiagonalBlockDefinitions(Database db, Editor ed) { using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); string blockDir = GetBlockDirectory(); foreach (double len in DiagonalBarLengths) { string blockName = $"{DiagonalBarPrefix}{len:0}mm"; if (bt.Has(blockName)) continue; LoadDiagonalBlock(db, len, ed); } tr.Commit(); } } // 加载单个斜拉杆块 private bool LoadDiagonalBlock(Database db, double length, Editor ed) { string blockName = $"{DiagonalBarPrefix}{length:0}mm"; string blockPath = GetBlockFilePath(length); if (string.IsNullOrEmpty(blockPath)) { ed.WriteMessage($"\n斜拉杆块文件未找到: {blockName}"); return false; } try { using (Database sourceDb = new Database(false, true)) { sourceDb.ReadDwgFile(blockPath, FileOpenMode.OpenForReadAndAllShare, false, null); sourceDb.CloseInput(true); using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); if (!bt.Has(blockName)) { db.Insert(blockName, sourceDb, true); ed.WriteMessage($"\n已加载斜拉杆块: {blockName}"); } tr.Commit(); } } return true; } catch (System.Exception ex) { ed.WriteMessage($"\n加载块 {blockName} 时出错: {ex.Message}"); return false; } } // 获取块文件目录 private string GetBlockDirectory() { string scaffoldBlocksDir = Path.Combine(_pluginDirectory, BlockDirectoryName); if (!Directory.Exists(scaffoldBlocksDir)) { try { Directory.CreateDirectory(scaffoldBlocksDir); } catch { return _pluginDirectory; } } return scaffoldBlocksDir; } // 获取块文件路径 private string GetBlockFilePath(double length) { string blockName = $"{DiagonalBarPrefix}{length:0}mm"; string blockDir = GetBlockDirectory(); string[] extensions = { ".dwg", ".DWG", ".dxf", ".DXF" }; foreach (string ext in extensions) { string path = Path.Combine(blockDir, $"{blockName}{ext}"); if (File.Exists(path)) return path; } return null; } #endregion }
}
CAD运行测试中y以下问题依然存在:
隔二布一:水平方向隔二的两跨内中间垂直线未布置斜拉杆,而在水平方向隔二的两跨上水平线上布置了两根斜拉杆,垂直方向隔二的两跨内中间水平线未布置斜拉杆,而在垂直方向隔二的两跨右侧垂直线上布置了两根斜拉杆
隔三布一:水平方向隔三的三跨内中间垂直线未布置斜拉杆,而在水平方向隔三的三跨上水平线上布置了三根斜拉杆,垂直方向隔三的三跨内中间两根水平线未布置斜拉杆,而在垂直方向隔三的三跨右侧垂直线上布置了三根斜拉杆
斜拉杆还是匹配错误900mm的线段长布置了600mm的斜拉杆
四条边布置的斜拉杆有两条边布置斜拉杆方向错误,四条边底部和右侧斜拉杆要以线段的镜像布置已改对了,但左侧和上面的反而改错了
将代码中问题修改成完整的一套代码
最新发布