System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)的问题

本文深入探讨了在VB.net代码转换过程中,由C#程序中的数学操作自动生成的复杂语句。解释了原因在于防止传递错误,并提供了详细链接以供进一步学习。

今天在学习一段VB.net的代码时看到了这样的语句System.Math.Min(System.Threading.Interlocked.Increment(i), i - 1)

百思不得其解,在Google上搜了一把,发现这段语句是C#程序转为VB.net时自动生成的。由于在C#程序中使用了诸如

i++之类得得语句,所以为了防止转换后的VB.net程序传递错误的值,就将源程序中的语句自动转换为如上的复杂的语句了。

下面的两个网址对此有解释。

http://www.telerik.com/community/forums/open-source-projects/code-converter/system-math-max-system-threading-interlocked-increment-k-k-1.aspx

http://stackoverflow.com/questions/1828728/why-use-system-threading-interlocked-decrement-instead-of-minus

using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Net.Http; using System.Net.Http.Headers; using System.Threading; using System.Threading.Tasks; public class DownloadService : IDisposable { private readonly HttpClient _httpClient; private CancellationTokenSource _cts = new(); private bool _isPaused; private readonly ConcurrentDictionary<string, FileDownloadState> _downloadStates = new(); private long _totalBytesRead; private long _totalSize; private readonly ConcurrentDictionary<string, byte> _allTempFiles = new ConcurrentDictionary<string, byte>(); public DownloadService() { _httpClient = new HttpClient(new HttpClientHandler { AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate }); _httpClient.DefaultRequestHeaders.AcceptEncoding.Add(new StringWithQualityHeaderValue("gzip")); } public async Task DownloadAllAsync( Dictionary<string, string> files, IProgress<DownloadProgressReport> progress, int maxDegreeOfParallelism = 8) { var options = new ParallelOptions { MaxDegreeOfParallelism = maxDegreeOfParallelism, CancellationToken = _cts.Token }; // 预计算总大小 await PrecalculateTotalSizeAsync(files, progress); // 重置进度计数器 _totalBytesRead = 0; int completedFiles = 0; await Parallel.ForEachAsync(files, options, async (file, ct) => { var (fileName, url) = file; var savePath = Path.Combine(FileSystem.AppDataDirectory, fileName); var tempPath = Path.GetTempFileName(); _allTempFiles[tempPath] = 0;//记录到全局临时文件集合 try { // 记录下载状态 var state = new FileDownloadState(fileName, tempPath); _downloadStates[fileName] = state; long startPosition = File.Exists(savePath) ? new FileInfo(savePath).Length : 0; long downloadedForFile = 0; using var request = new HttpRequestMessage(HttpMethod.Get, url); if (startPosition > 0) request.Headers.Range = new RangeHeaderValue(startPosition, null); using var response = await _httpClient.SendAsync( request, HttpCompletionOption.ResponseHeadersRead, ct); response.EnsureSuccessStatusCode(); var contentLength = response.Content.Headers.ContentLength ?? 0; state.TotalSize = startPosition + contentLength; using var contentStream = await response.Content.ReadAsStreamAsync(); using var fileStream = new FileStream( tempPath, FileMode.Create, FileAccess.Write, FileShare.None, 8192, FileOptions.Asynchronous); var buffer = new byte[8192]; while (!ct.IsCancellationRequested) { if (_isPaused) { await Task.Delay(500, ct); continue; } int bytesRead = await contentStream.ReadAsync(buffer, 0, buffer.Length, ct); if (bytesRead == 0) break; await fileStream.WriteAsync(buffer, 0, bytesRead, ct); // 更新进度 downloadedForFile += bytesRead; state.DownloadedBytes = downloadedForFile + startPosition; Interlocked.Add(ref _totalBytesRead, bytesRead); progress?.Report(new DownloadProgressReport { TotalFiles = files.Count, CompletedFiles = completedFiles, DownloadedBytes = _totalBytesRead, TotalSize = _totalSize, CurrentFileName = fileName, CurrentProgress = state.Progress }); } // 完成文件处理 File.Move(tempPath, savePath, true); // 移动成功后,从_allTempFiles中移除 _allTempFiles.TryRemove(tempPath, out _); Interlocked.Increment(ref completedFiles); } catch (OperationCanceledException) { // 取消操作的正常处理 } catch (Exception ex) { // 错误处理 Console.WriteLine($"Download error: {ex.Message}"); } finally { // 清理临时文件 SafeDeleteFile(tempPath); // 尝试从_allTempFiles中移除(如果之前没有移除) _allTempFiles.TryRemove(tempPath, out _); _downloadStates.TryRemove(fileName, out _); progress?.Report(new DownloadProgressReport { TotalFiles = files.Count, CompletedFiles = completedFiles, DownloadedBytes = _totalBytesRead, TotalSize = _totalSize }); } }); } private async Task PrecalculateTotalSizeAsync( Dictionary<string, string> files, IProgress<DownloadProgressReport> progress) { _totalSize = 0; int processedFiles = 0; await Parallel.ForEachAsync(files, new ParallelOptions { MaxDegreeOfParallelism = 4 }, async (file, ct) => { try { using var response = await _httpClient.SendAsync( new HttpRequestMessage(HttpMethod.Head, file.Value), ct); var length = response.Content.Headers.ContentLength ?? 0; var savePath = Path.Combine(FileSystem.AppDataDirectory, file.Key); if (File.Exists(savePath)) { var fileInfo = new FileInfo(savePath); length -= Math.Min(fileInfo.Length, length); } Interlocked.Add(ref _totalSize, length); } catch { // 忽略错误,继续其他文件 } finally { Interlocked.Increment(ref processedFiles); progress?.Report(new DownloadProgressReport { TotalFiles = files.Count, PrecalculatedFiles = processedFiles, TotalSize = _totalSize }); } }); } public void Pause() => _isPaused = true; public void Resume() => _isPaused = false; public void Cancel() { // 1. 取消所有下载任务 _cts.Cancel(); // 2. 删除所有记录在_allTempFiles中的临时文件 foreach (var tempPath in _allTempFiles.Keys) { SafeDeleteFile(tempPath); } // 3. 清空状态 _allTempFiles.Clear(); _downloadStates.Clear(); _cts = new CancellationTokenSource(); _isPaused = false; _totalBytesRead = 0; } private void SafeDeleteFile(string path) { try { if (File.Exists(path)) File.Delete(path); } catch { // 忽略删除错误 } } public void Dispose() => _httpClient?.Dispose(); } public class DownloadProgressReport { public int TotalFiles { get; set; } public int CompletedFiles { get; set; } public int PrecalculatedFiles { get; set; } public long DownloadedBytes { get; set; } public long TotalSize { get; set; } public string CurrentFileName { get; set; } public double CurrentProgress { get; set; } public double OverallProgress => TotalSize > 0 ? (double)DownloadedBytes / TotalSize : 0; public int FileProgress => TotalFiles > 0 ? (CompletedFiles * 100) / TotalFiles : 0; } public class FileDownloadState { public string FileName { get; } public string TempPath { get; } public long DownloadedBytes { get; set; } public long TotalSize { get; set; } public double Progress => TotalSize > 0 ? (double)DownloadedBytes / TotalSize : 0; public FileDownloadState(string fileName, string tempPath) { FileName = fileName; TempPath = tempPath; } } 这个service在断网续传一次时没问题,但是在二次断网后,页面进度不实时显示,在原有功能不改变的情况下,调整一下啊,给我一份完整的代码
09-13
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.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; namespace ScaffoldAutomation { public class DiagonalBarPlacer { // 配置常量 private const string Diagonal极Layer = "斜拉杆"; 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; // 斜拉杆偏移距离(毫米) private const double OffsetDistance = 1.0; 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(sel极s); 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}\n{ex.StackTrace}"); } } #region 新增自动检查功能 // 删除田字型框内及周边的斜拉杆 private int DeleteBarsInPatternTwoArea(Database db, Transaction tr, int row, int col, Editor ed) { int deletedCount = 0; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); // 定义田字型区域 (3x3单元) int startRow = Math.Max(0, row - 1); int endRow = Math.Min(_grid.RowCount - 1, row + 1); int startCol = Math.Max(0, col - 1); int endCol = Math.Min(_grid.ColumnCount - 1, col + 1); // 收集要删除的边 var edgesToDelete = new List<GridEdge>(); // 收集水平边 for (int r = startRow; r <= endRow; r++) { for (int c = startCol; c <= endCol; c++) { // 上边 var topEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == c); if (topEdge != null) edgesToDelete.Add(topEdge); // 下边 var bottomEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r + 1 && e.ColIndex == c); if (bottomEdge != null) edgesToDelete.Add(bottomEdge); // 左边 var leftEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c && e.RowIndex == r); if (leftEdge != null) edgesToDelete.Add(leftEdge); // 右边 var rightEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c + 极 && e.RowIndex == r); if (rightEdge != null) edgesToDelete.Add(rightEdge); } } // 删除中间跨的水平杆 for (int r = startRow; r <= endRow; r++) { // 中间列 int midCol = col + 1; if (midCol < _grid.ColumnCount) { var midEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == midCol); if (midEdge != null) edgesToDelete.Add(midEdge); } } // 删除这些边上的斜拉杆 foreach (var edge in edgesToDelete) { Point3d midPoint = new Point3d( (edge.StartPoint.X + edge.EndPoint.X) / 2, (edge.StartPoint.Y + edge.EndPoint.Y) / 2, 0); // 查找并删除该位置的斜拉杆 foreach (ObjectId id in btr) { BlockReference br = tr.GetObject(id, OpenMode.ForRead) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer && br.Position.DistanceTo(midPoint) < Tolerance) { br.UpgradeOpen(); br.Erase(); deletedCount++; ed.WriteMessage($"\n删除斜拉杆: ({midPoint.X:F0},{midPoint.Y:F0})"); break; } } } return deletedCount; } // 删除井字型框内及周边的斜拉杆 private int DeleteBarsInPatternThreeArea(Database db, Transaction tr, int row, int col, Editor ed) { int deletedCount = 0; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); // 定义井字型区域 (4x4单元) int startRow = Math.Max(0, row - 1); int endRow = Math.Min(_grid.RowCount - 1, row + 2); int startCol = Math.Max(0, col - 1); int endCol = Math.Min(_grid.ColumnCount - 1, col + 2); // 收集要删除的边 var edgesToDelete = new List<GridEdge>(); // 收集水平边 for (int r = startRow; r <= endRow; r++) { for (int c = startCol; c <= endCol; c++) { // 上边 var topEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == c); if (topEdge != null) edgesToDelete.Add(topEdge); // 下边 var bottomEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r + 1 && e.ColIndex == c); if (bottomEdge != null) edgesToDelete.Add(bottomEdge); // 左边 var leftEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c && e.RowIndex == r); if (leftEdge != null) edgesToDelete.Add(leftEdge); // 右边 var rightEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c + 1 && e.RowIndex == r); if (rightEdge != null) edgesToDelete.Add(rightEdge); } } // 删除中间跨的水平杆 for (int r = startRow; r <= endRow; r++) { // 中间列1 int midCol1 = col + 1; if (midCol1 < _grid.ColumnCount) { var midEdge1 = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == midCol1); if (midEdge1 != null) edgesToDelete.Add(midEdge1); } // 中间列2 int midCol2 = col + 2; if (midCol2 < _grid.ColumnCount) { var midEdge2 = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == midCol2); if (midEdge2 != null) edgesToDelete.Add(midEdge2); } } // 删除这些边上的斜拉杆 foreach (var edge in edgesToDelete) { Point3d midPoint = new Point3d( (edge.StartPoint.X + edge.EndPoint.X) / 2, (edge.StartPoint.Y + edge.EndPoint.Y) / 2, 0); // 查找并删除该位置的斜极杆 foreach (ObjectId id in btr) { BlockReference br = tr.GetObject(id, OpenMode.ForRead) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer && br.Position.DistanceTo(midPoint) < Tolerance) { br.UpgradeOpen(); br.Erase(); deletedCount++; ed.WriteMessage($"\n删除斜拉杆: ({midPoint.X:F0},{midPoint.Y:F0})"); break; } } } return deletedCount; } #endregion #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) => p1.DistanceTo(p2) <= _tolerance; public int GetHashCode(Point3d p) => (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 ConcurrentDictionary<Point3d, bool>(new Point3dComparer(Tolerance)); long totalIntersections = 0; // 使用空间分区提高性能 var lineBuckets = new Dictionary<(int, int), List<Line>>(); const double gridSize = 5000.0; // 网格大小5米 // 并行处理线段分配 Parallel.ForEach(axisLines, line => { Point3d min = new Point3d( Math.Min(line.StartPoint.X, line.EndPoint.X), Math.Min(line.StartPoint.Y, line.EndPoint.Y), 0); Point3d max = new Point3d( Math.Max(line.StartPoint.X, line.EndPoint.X), Math.Max(line.StartPoint.Y, line.EndPoint.Y), 0); int minX = (int)(min.X / gridSize); int minY = (int)(min.Y / gridSize); int maxX = (int)(max.X / gridSize); int maxY = (int)(max.Y / gridSize); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { var key = (x, y); lock (lineBuckets) { if (!lineBuckets.ContainsKey(key)) lineBuckets[key] = new List<Line>(); lineBuckets[key].Add(line); } } } }); // 并行处理交点计算 var keys = lineBuckets.Keys.ToArray(); Parallel.For(0, keys.Length, i => { var bucket = lineBuckets[keys[i]]; for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { var neighborKey = (keys[i].Item1 + dx, keys[i].Item2 + dy); if (!lineBuckets.ContainsKey(neighborKey)) continue; var neighborBucket = lineBuckets[neighborKey]; for (int a = 0; a < bucket.Count; a++) { for (int b = a + 1; b < neighborBucket.Count; b++) { Point3dCollection pts = new Point3dCollection(); bucket[a].IntersectWith( neighborBucket[b], Intersect.ExtendBoth, pts, IntPtr.Zero, IntPtr.Zero); foreach (Point3d pt in pts) { intersections[RoundPoint(pt, Tolerance)] = true; Interlocked.Increment(ref totalIntersections); } } } } } }); ed.WriteMessage($"\n找到 {intersections.Count} 个有效网格交点(总交点: {totalIntersections})"); return intersections.Keys.ToList(); } // 构建网格结构 private GridStructure BuildGridStructure(List<极3d> intersections, List<Line> axisLines, Editor ed) { var grid = new GridStructure(); // 分离X和Y坐标(带容差) var xCoords = intersections .Select(p => Math.Round(p.X / Tolerance) * Tolerance) .Distinct() .OrderBy(x => x) .ToList(); var yCoords = intersections .Select(p => Math.Round(p.Y / Tolerance) * Tolerance) .Distinct() .OrderByDescending(y => y) // Y坐标从大到小排序(顶部为0) .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 == 极), IsBottomEdge = (row == yCoords.Count - 1) }); } } } // 创建垂直边(处理分段线段) for (int col = 0; col < xCoords.Count; col++) { double x = xCoords[col]; // 收集该列上的所有交点 var colPoints = intersections .Where(p => Math.Abs(p.X - x) < Tolerance) .OrderByDescending(p => p.Y) .ToList(); // 处理相邻交点间的线段 for (int i = 0; i < colPoints.Count - 1; i++) { Point3d start = colPoints[i]; Point3d end = colPoints[i + 1]; double segmentLength = start.DistanceTo(end); // 查找实际存在的线段 Line actualSegment = FindActualSegment(axisLines, start, end, Tolerance); if (actualSegment != null) { grid.VerticalEdges.Add(new GridEdge { StartPoint = start, EndPoint = end, Length = actualSegment.Length, // 使用实际线段长度 RowIndex = i, ColIndex = col, IsHorizontal = false, IsOuterEdge = (col == 0 || col == xCoords.Count - 1), IsLeftEdge = (col == 0), IsRightEdge = (col == xCoords.Count - 1) }); } } } return grid; } // 查找实际存在的线段 private Line FindActualSegment(List<Line> axisLines, Point3d start, Point3d end, double tolerance) { foreach (Line line in axisLines) { if (IsPointOnLine(line, start, tolerance) && IsPointOnLine(line, end, tolerance) && Math.Abs(line.Length - start.DistanceTo(end)) < tolerance) { return line; } } return null; } // 检查点是否在直线上(带容差) 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>(); // 避免重复布置 // 添加整体进度报告 int totalEdges = _grid.HorizontalEdges.Count + _grid.VerticalEdges.Count; int processed = 0; int lastReported = 0; switch (mode) { case 1: // 隔一布一 diagonalCount += PlacePatternOne(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; case 2: // 隔二布一 diagonalCount += PlacePatternTwo(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; case 3: // 隔三布一 diagonalCount += PlacePatternThree(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; case 4: // 满布 diagonalCount += PlaceFullPattern(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); 极 break; } return diagonalCount; } // 模式1: 隔一布一 private int PlacePatternOne(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; for (int row = 0; row < _grid.RowCount; row++) { // 每10行报告一次进度 if (row % 10 == 0) { ed.WriteMessage($"\n处理中: 行 {row}/{_grid.RowCount} ({(double)row / _grid.RowCount:P0})"); if (CheckForUserCancel(ed)) { ed.WriteMessage("\n操作已取消"); return count; } } 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, ref processed, totalEdges, ref lastReported); } } } ed.WriteMessage($"\n隔一布一模式: 布置了 {count} 根斜拉杆"); return count; } // 模式2: 隔二布一(添加自动检查功能) private int PlacePatternTwo(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; int deletedCount = 0; // 单元布置:只布置左上角单元(每3行3列) for (int row = 0; row < _grid.RowCount; row += 3) { for (int col = 0; col < _grid.ColumnCount; col += 3) { // 删除田字型区域内的斜拉杆 deletedCount += DeleteBarsInPatternTwoArea(db, tr, row, col, ed); // 布置单元四边 count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } // 布置中间垂直边(第1列) for (int col = 1; col < _grid.ColumnCount; col += 3) { for (int row = 0; row < _grid.Row极Count; row++) { // 跳过中间行(行索引为1 mod 3) if (row % 3 == 1) continue; var edges = _grid.VerticalEdges .Where(e => e.ColIndex == col && e.RowIndex == row) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } // 布置中间水平边(第1行) for (int row = 1; row < _grid.RowCount; row += 3) { for (int col = 0; col < _grid.ColumnCount; col++) { // 跳过中间列(列索引为1 mod 3) if (col % 3 == 1) continue; var edges = _grid.HorizontalEdges .Where(e => e.RowIndex == row && e.ColIndex == col) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } ed.WriteMessage($"\n隔二布一模式: 删除了 {deletedCount} 根斜拉杆,布置了 {count极} 根斜拉杆"); return count; } // 模式3: 隔三布一(添加自动检查功能) private int PlacePatternThree(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; int deletedCount = 0; // 单元布置:只布置左上角单元(每4行4列) for (int row = 0; row < _grid.RowCount; row += 4) { for (int col = 0; col < _grid.ColumnCount; col += 4) { // 删除井字型区域内的斜拉杆 deletedCount += DeleteBarsInPatternThreeArea(db, tr, row, col, ed); // 布置单元四边 count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } // 布置中间垂直边(第1列和第2列) for (int col = 1; col < _grid.ColumnCount; col += 4) // 每4列的第1列 { for (int row = 0; row < _grid.RowCount; row++) { // 跳过中间行(行索引为1或2 mod 4) if (row % 4 == 1 || row % 4 == 2) continue; var edges = _grid.VerticalEdges .Where(e => e.ColIndex == col && e.RowIndex == row) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } for (int col = 2; col < _grid.ColumnCount; col += 4) // 每4列的第2列 { for (int row = 0; row < _grid.RowCount; row++) { // 跳过中间行(行索引为1或2 mod 4) if (row % 4 == 1 || row % 4 == 2) continue; var edges = _grid.VerticalEdges .Where(e => e.ColIndex == col && e.RowIndex == row) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } // 布置中间水平边(第1行和第2行) for (int row = 1; row < _grid.RowCount; row += 4) // 每4行的第1行 { for (int col = 0; col < _grid.ColumnCount; col++) { // 跳过中间列(列索引为1或2 mod 4) if (col % 4 == 1 || col % 4 == 2) continue; var edges = _grid.HorizontalEdges .Where(e => e.RowIndex == row && e.ColIndex == col) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } for (int row = 2; row < _grid.RowCount; row += 4) // 每4行的第2行 { for (int col = 0; col < _grid.ColumnCount; col++) { // 跳过中间列(列索引为1或2 mod 4) if (col % 4 == 1 || col % 4 == 2) continue; var edges = _grid.HorizontalEdges .Where(e => e.RowIndex == row && e.ColIndex == col) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } ed.WriteMessage($"\n隔三布一模式: 删除了 {deletedCount} 根斜拉杆,布置了 {count} 根斜拉杆"); return count; } // 模式4: 满布 private int PlaceFullPattern(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; // 布置所有水平边 foreach (GridEdge edge in _grid.HorizontalEdges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } // 布置所有垂直边 foreach (GridEdge edge in _grid.VerticalEdges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } 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, ref int processed, int totalEdges, ref int lastReported) { 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, ref processed, totalEdges, ref lastReported); } // 下边 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, ref processed, totalEdges, ref lastReported); } // 左边 var leftEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == col && e.RowIndex == row); if (leftEdge != null) { count += PlaceSingleBar(leftEdge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } // 右边 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, ref processed, totalEdges, ref lastReported); } return count; } // 布置单根斜拉杆(优化旋转角度计算) private int PlaceSingleBar(GridEdge edge, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Database db, Transaction tr, Editor ed, ref int processed, int totalEdges, ref int lastReported) { // 进度报告 if (processed - lastReported > 1000) { ed.WriteMessage($"\n布置进度: {processed}/{totalEdges} ({processed * 100.0 / totalEdges:F1}%)"); lastReported = processed; if (CheckForUserCancel(ed)) { ed.WriteMessage("\n操作已取消"); return 0; } } processed++; // 生成边唯一标识 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):极1}mm)"); ed.WriteMessage($"\n线段坐标: ({edge.StartPoint.X:F0},{edge.StartPoint.Y:F0}) -> ({edge.EndPoint.X:F0},{edge.EndPoint.Y:F0})"); 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 = CalculateRotationAngle(edge); // 对外侧边进行偏移处理 if (edge.IsOuterEdge) { 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); // 添加详细日志 string positionDesc = GetPositionDescription(edge); ed.WriteMessage($"\n布置: {blockName} ({edge.Length:F0}mm)({midPoint.X:F0},{midPoint.Y:F0}), " + $"位置={positionDesc}, " + $"角度={rotation * 180 / Math.PI:F0}度"); return 1; } // 计算旋转角度(优化逻辑) private double CalculateRotationAngle(GridEdge edge) { // 计算方向向量 Vector3d direction = edge.EndPoint - edge.StartPoint; // 水平边 if (edge.IsHorizontal) { // 水平边:顶部0度,底部180度 return edge.IsTopEdge ? 0.0 : Math.PI; } // 垂直边 else { // 垂直边:左侧90度,右侧270度 return edge.IsLeftEdge ? Math.PI / 2 : 3 * Math.PI / 2; } } // 获取位置描述 private string GetPositionDescription(GridEdge edge) { if (edge.IsLeftEdge) return "左侧"; if (edge.IsRightEdge) return "右侧"; if (edge.IsTopEdge) return "上方"; if (edge.IsBottomEdge) return "下方"; return "内部"; } // 获取最接近的标准长度(支持组合匹配) private double GetClosestDiagonalLength(double segmentLength) { // 精确匹配优先 foreach (double len in DiagonalBarLengths) { if (Math.Abs(len - segmentLength) < Tolerance) return len; } // 尝试组合匹配(如900=600+300) if (segmentLength > DiagonalBarLengths.Min()) { foreach (double len1 in DiagonalBarLengths) { double remaining = segmentLength - len1; if (remaining <= 0) continue; foreach (double len2 in DiagonalBarLengths) { if (Math.Abs(remaining - len2) < Tolerance) { // 返回较大的标准长度(主杆) return Math.Max(len1, len2); } } } } // 找不到精确匹配则返回最接近的 return DiagonalBarLengths .OrderBy(len => Math.Abs(len - segmentLength)) .First(); } #endregion #region 斜拉杆翻转功能 [CommandMethod("FlipDiagonals", "FD", CommandFlags.Modal)] public void FlipDiagonals() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { // 提示用户选择斜拉杆 PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\n选择要翻转的斜拉杆 (框选): "; pso.AllowSubSelections = true; pso.SingleOnly = false; pso.RejectObjectsFromNonCurrentSpace = true; // 设置图层过滤器 TypedValue[] filterList = { new TypedValue((int)DxfCode.LayerName, DiagonalBarLayer) }; SelectionFilter filter = new SelectionFilter(filterList); PromptSelectionResult selResult = ed.GetSelection(pso, filter); if (selResult.Status != PromptStatus.OK) return; int flipCount = 0; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); foreach (SelectedObject selObj in selResult.Value) { BlockReference br = tr.GetObject(selObj.ObjectId, OpenMode.ForWrite) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer) { // 获取原始方向 string originalDirection = GetDiagonalDirection(br.Rotation); // 计算翻转角度(180度) double newRotation = br.Rotation + Math.PI; // 角度归一化到0-2π范围 if (newRotation > 2 * Math.PI) newRotation -= 2 * Math.PI; // 获取新方向 string newDirection = GetDiagonalDirection(newRotation); // 应用新角度 br.Rotation = newRotation; flipCount++; // 更新日志 ed.WriteMessage($"\n翻转: {originalDirection}→{newDirection} " + $"({br.Rotation * 180 / Math.PI:F0}°→{newRotation * 180 / Math.PI:F0}°)"); } } tr.Commit(); } ed.WriteMessage($"\n成功翻转 {flipCount} 根斜拉杆"); } catch (System.Exception ex) { ed.WriteMessage($"\n翻转错误: {ex.Message}"); } } // 获取斜拉杆方向描述 private string GetDiagonalDirection(double rotation) { double degrees = rotation * 180 / Math.PI; // 简化到0-360范围 degrees %= 360; if (degrees < 0) degrees += 360; // 方向分类 if (degrees >= 315 || degrees < 45) return "上"; if (degrees >= 45 && degrees < 135) return "右"; if (degrees >= 135 && degrees < 225) return "下"; return "左"; } #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.Contains极(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", ".dx极", ".DXF" }; foreach (string ext in extensions) { string path = Path.Combine(blockDir, $"{blockName}{ext}"); if (File.Exists(path)) return path; } return null; } // 用户取消检查 private bool CheckForUserCancel(Editor ed) { try { PromptResult result = ed.GetString("\n按ESC取消操作 [按回车继续]"); return result.Status == PromptStatus.Cancel; } catch { return false; } } #endregion } } CS0103当前上下文中不存在名称DiagonalBarLayer CS0103当前上下文中不存在名称DiagonalBarLayer CS0103当前上下文中不存在名称“sel极s” CS0103当前上下文中不存在名称“极” CS0103当前上下文中不存在名称“DiagonalBarLayer” CS0103当前上下文中不存在名称“DiagonalBarLayer CS1503参数1:无法从“System.Collections.Generic.List<Autodesk.AutoCAD.Geometry.Point3d>"转换为“System.Collections.Generic.List<极3d>" CS0246未能找到类型或命名空间名“极3d”(是否缺少using 指令或程序集引用?) CS0103当前上下文中不存在名称极 CS0103当前上下文中不存在名称极 CS1002应输入; CS1061“DiagonalBarPlacer.GnidStructure"未包含”Row极Count"的定义,并且找不到可接受第一个"DiagonalBarPlacer.GridStructure"“类型参数的可访问扩展方法"Row极Count"(是否缺少using指令或程序集引用?) CS0103当前上下文中不存在名称count极 CS0103当前上下文中不存在名称DiagonalBarLayer" CS0103当前上下文中不存在名称“DiagonalBarLayer” CS0103当前上下文中不存在名称“DiagonalBarLayer CS0103当前上下文中不存在名称DiagonalBarLayer CS1061“Dictionary<string, HashSet<string>>"未包含”Contains极”的定义,并且找不到可接受第一个"Dictonary<string, HashSet<string>>“类型参数的可访问扩展方法"Contains极”(是否缺少using指令或程序集引用?)
07-11
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.Concurrent; using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; using System.Threading; using System.Threading.Tasks; 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; // 斜拉杆偏移距离(毫米) private const double OffsetDistance = 1.0; 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("\极无法生成有效的网格结构"); 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}\n{ex.StackTrace}"); } } #region 新增自动检查功能 // 删除田字型框内及周边的斜拉杆 private int DeleteBarsInPatternTwoArea(Database db, Transaction tr, int row, int col, Editor ed) { int deletedCount = 0; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); // 定义田字型区域 (3x3单元) int startRow = Math.Max(0, row - 1); int endRow = Math.Min(_grid.RowCount - 1, row + 1); int startCol = Math.Max(0, col - 1); int endCol = Math.Min(_grid.ColumnCount - 1, col + 1); // 收集要删除的边 var edgesToDelete = new List<GridEdge>(); // 收集水平边 for (int r = startRow; r <= endRow; r++) { for (int c = startCol; c <= endCol; c++) { // 上边 var topEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == c); if (topEdge != null) edgesToDelete.Add(topEdge); // 下边 var bottomEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r + 1 && e.ColIndex == c); if (bottomEdge != null) edgesToDelete.Add(bottomEdge); // 左边 var leftEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c && e.RowIndex == r); if (leftEdge != null) edgesToDelete.Add(leftEdge); // 右边 var rightEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c + 1 && e.RowIndex == r); if (rightEdge != null) edgesToDelete.Add(rightEdge); } } // 删除中间跨的水平杆 for (int r = startRow; r <= endRow; r++) { // 中间列 int midCol = col + 1; if (midCol < _grid.ColumnCount) { var midEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == midCol); if (midEdge != null) edgesToDelete.Add(midEdge); } } // 删除这些边上的斜拉杆 foreach (var edge in edgesToDelete) { Point3d midPoint = new Point3d( (edge.StartPoint.X + edge.EndPoint.X) / 2, (edge.StartPoint.Y + edge.EndPoint.Y) / 2, 0); // 查找并删除该位置的斜拉杆 foreach (ObjectId id in btr) { BlockReference br = tr.GetObject(id, OpenMode.ForRead) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer && br.Position.DistanceTo(midPoint) < Tolerance) { br.UpgradeOpen(); br.Erase(); deletedCount++; ed.WriteMessage($"\n删除斜拉杆: ({midPoint.X:F0},{midPoint.Y:F0})"); break; } } } return deletedCount; } // 删除井字型框内及周边的斜拉杆 private int DeleteBarsInPatternThreeArea(Database db, Transaction tr, int row, int col, Editor ed) { int deletedCount = 0; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpace极, OpenMode.ForWrite); // 定义井字型区域 (4x4单元) int startRow = Math.Max(0, row - 1); int endRow = Math.Min(_grid.RowCount - 1, row + 2); int startCol = Math.Max(0, col - 1); int endCol = Math.Min(_grid.ColumnCount - 1, col + 2); // 收集要删除的边 var edgesToDelete = new List<GridEdge>(); // 收集水平边 for (int r = startRow; r <= endRow; r++) { for (int c = startCol; c <= endCol; c++) { // 上边 var topEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == c); if (topEdge != null) edgesToDelete.Add(topEdge); // 下边 var bottomEdge = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r + 1 && e.ColIndex == c); if (bottomEdge != null) edgesToDelete.Add(bottomEdge); // 左边 var leftEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c && e.RowIndex == r); if (leftEdge != null) edgesToDelete.Add(leftEdge); // 右边 var rightEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == c + 1 && e.RowIndex == r); if (rightEdge != null) edgesToDelete.Add(rightEdge); } } // 删除中间跨的水平杆 for (int r = startRow; r <= endRow; r++) { // 中间列1 int midCol1 = col + 1; if (midCol1 < _grid.ColumnCount) { var midEdge1 = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == mid极1); if (midEdge1 != null) edgesToDelete.Add(midEdge1); } // 中间列2 int midCol2 = col + 2; if (midCol2 < _grid.ColumnCount) { var midEdge2 = _grid.HorizontalEdges .FirstOrDefault(e => e.RowIndex == r && e.ColIndex == midCol2); if (midEdge2 != null) edgesToDelete.Add(midEdge2); } } // 删除这些边上的斜拉杆 foreach (var edge in edgesToDelete) { Point3d midPoint = new Point3d( (edge.StartPoint.X + edge.EndPoint.X) / 2, (edge.StartPoint.Y + edge.EndPoint.Y) / 2, 0); // 查找并删除该位置的斜拉杆 foreach (ObjectId id in btr) { BlockReference br = tr.GetObject(id, OpenMode.ForRead) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer && br.Position.DistanceTo(midPoint) < Tolerance) { br.UpgradeOpen(); br.Erase(); deletedCount++; ed.WriteMessage($"\n删除斜拉杆: ({midPoint.X:F0},{midPoint.Y:F0})"); break; } } } return deletedCount; } #endregion #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) => p1.DistanceTo(p2) <= _tolerance; public int GetHashCode(Point3d p) => (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 ConcurrentDictionary<Point3d, bool>(new Point3dComparer(Tolerance)); long totalIntersections = 0; // 使用空间分区提高性能 var lineBuckets = new Dictionary<(int, int), List<Line>>(); const double gridSize = 5000.0; // 网格大小5米 // 并行处理线段分配 Parallel.ForEach(axisLines, line => { Point3d min = new Point3d( Math.Min(line.StartPoint.X, line.EndPoint.X), Math.Min(line.StartPoint.Y, line.EndPoint.Y), 0); Point3d max = new Point3d( Math.Max(line.StartPoint.X, line.EndPoint.X), Math.Max(line.StartPoint.Y, line.EndPoint.Y), 0); int minX = (int)(min.X / gridSize); int minY = (int)(min.Y / gridSize); int maxX = (int)(max.X / gridSize); int maxY = (int)(max.Y / gridSize); for (int x = minX; x <= maxX; x++) { for (int y = minY; y <= maxY; y++) { var key = (x, y); lock (lineBuckets) { if (!lineBuckets.ContainsKey(key)) lineBuckets[key] = new List<Line>(); lineBuckets[key].Add(line); } } } }); // 并行处理交点计算 var keys = lineBuckets.Keys.ToArray(); Parallel.For(0, keys.Length, i => { var bucket = lineBuckets[keys[i]]; for (int dx = -1; dx <= 1; dx++) { for (int dy = -1; dy <= 1; dy++) { var neighborKey = (keys[i].Item1 + dx, keys[i].Item2 + dy); if (!lineBuckets.ContainsKey(neighborKey)) continue; var neighborBucket = lineBuckets[neighborKey]; for (int a = 0; a < bucket.Count; a++) { for (int b = a + 1; b < neighborBucket.Count; b++) { Point3dCollection pts = new Point3dCollection(); bucket[a].IntersectWith( neighborBucket[b], Intersect.ExtendBoth, pts, IntPtr.Zero, IntPtr.Zero); foreach (Point3d pt in pts) { intersections[RoundPoint(pt, Tolerance)] = true; Interlocked.Increment(ref totalIntersections); } } } } } }); ed.WriteMessage($"\n找到 {intersections.Count} 个有效网格交点(总交点: {totalIntersections})"); return intersections.Keys.ToList(); } // 构建网格结构 private GridStructure BuildGridStructure(List<Point3d> intersections, List<Line> axisLines, Editor ed) { var grid = new GridStructure(); // 分离X和Y坐标(带容差) var xCoords = intersections .Select(p => Math.Round(p.X / Tolerance) * Tolerance) .Distinct() .OrderBy(x => x) .ToList(); var yCoords = intersections .Select(p => Math.Round(p.Y / Tolerance) * Tolerance) .Distinct() .OrderByDescending(y => y) // Y坐标从大到小排序(顶部为0) .ToList(); grid.XCoordinates = x极Coords; 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++) { double x = xCoords[col]; // 收集该列上的所有交点 var colPoints = intersections .Where(p => Math.Abs(p.X - x) < Tolerance) .OrderByDescending(p => p.Y) .ToList(); // 处理相邻交点间的线段 for (int i = 0; i < colPoints.Count - 1; i++) { Point3d start = colPoints[i]; Point3d end = colPoints[i + 1]; double segmentLength = start.DistanceTo(end); // 查找实际存在的线段 Line actualSegment = FindActualSegment(axisLines, start, end, Tolerance); if (actualSegment != null) { grid.VerticalEdges.Add(new GridEdge { StartPoint = start, EndPoint = end, Length = actualSegment.Length, // 使用实际线段长度 RowIndex = i, ColIndex = col, IsHorizontal = false, IsOuterEdge = (col == 0 || col == xCoords.Count - 1), IsLeftEdge = (col == 0), IsRightEdge = (col == xCoords.Count - 1) }); } } } return grid; } // 查找实际存在的线段 private Line FindActualSegment(List<Line> axisLines, Point3d start, Point3d end, double tolerance) { foreach (Line line in axisLines) { if (IsPointOnLine(line, start, tolerance) && IsPointOnLine(line, end, tolerance) && Math.Abs(line.Length - start.DistanceTo(end)) < tolerance) { return line; } } return null; } // 检查点是否在直线上(带容差) 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, Point3极 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>(); // 避免重复布置 // 添加整体进度报告 int totalEdges = _grid.HorizontalEdges.Count + _grid.VerticalEdges.Count; int processed = 0; int lastReported = 0; switch (mode) { case 1: // 隔一布一 diagonalCount += PlacePatternOne(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; case 2: // 隔二布一 diagonalCount += PlacePatternTwo(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; case 3: // 隔三布一 diagonalCount += PlacePatternThree(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; case 4: // 满布 diagonalCount += PlaceFullPattern(db, tr, btr, bt, placedEdges, ed, ref processed, totalEdges, ref lastReported); break; } return diagonalCount; } // 模式1: 隔一布一 private int PlacePatternOne(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; for (int row = 0; row < _grid.RowCount; row++) { // 每10行报告一次进度 if (row % 10 == 0) { ed.WriteMessage($"\n处理中: 行 {row}/{_grid.RowCount} ({(double)row / _grid.RowCount:P0})"); if (CheckForUserCancel(ed)) { ed.WriteMessage("\n操作已取消"); return count; } } 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, ref processed, totalEdges, ref lastReported); } } } ed.WriteMessage($"\n隔一布一模式: 布置了 {count} 根斜拉杆"); return count; } // 模式2: 隔二布一(添加自动检查功能) private int PlacePatternTwo(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; int deletedCount = 0; // 单元布置:只布置左上角单元(每3行3列) for (int row = 0; row < _grid.RowCount; row += 3) { for (int col = 0; col < _grid.ColumnCount; col += 3) { // 删除田字型区域内的斜拉杆 deletedCount += DeleteBarsInPatternTwoArea(db, tr, row, col, ed); // 布置单元四边 count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } // 布置中间垂直边(第1列) for (int col = 1; col < _grid.ColumnCount; col += 3) { for (int row = 0; row < _grid.RowCount; row++) { // 跳过中间行(行索引为1 mod 3) if (row % 3 == 1) continue; var edges = _grid.VerticalEdges .Where(e => e.ColIndex == col && e.RowIndex == row) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } // 布置中间水平边(第1行) for (int row = 1; row < _grid.RowCount; row += 3) { for (int col = 0; col < _grid.ColumnCount; col++) { // 跳过中间列(列索引为1 mod 3) if (col % 3 == 1) continue; var edges = _grid.HorizontalEdges .Where(e => e.RowIndex == row && e.ColIndex == col) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } ed.WriteMessage($"\n隔二布一模式: 删除了 {deletedCount} 根斜拉杆,布置了 {count} 根斜拉杆"); return count; } // 模式3: 隔三布一(添加自动检查功能) private int PlacePatternThree(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEd极, ref int lastReported) { int count = 0; int deletedCount = 0; // 单元布置:只布置左上角单元(每4行4列) for (int row = 0; row < _grid.RowCount; row += 4) { for (int col = 0; col < _grid.ColumnCount; col += 4) { // 删除井字型区域内的斜拉杆 deletedCount += DeleteBarsInPatternThreeArea(db, tr, row, col, ed); // 布置单元四边 count += PlaceCellEdges(row, col, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } // 布置中间垂直边(第1列和第2列) for (int col = 1; col < _grid.ColumnCount; col += 4) // 每4列的第1列 { for (int row = 0; row < _grid.RowCount; row++) { // 跳过中间行(行索引为1或2 mod 4) if (row % 4 == 1 || row % 4 == 2) continue; var edges = _grid.VerticalEdges .Where(e => e.ColIndex == col && e.RowIndex == row) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } for (int col = 2; col < _grid.ColumnCount; col += 4) // 每4列的第2列 { for (int row = 0; row < _grid.RowCount; row++) { // 跳过中间行(行索引为1或2 mod 4) if (row % 4 == 1 || row % 4 == 2) continue; var edges = _grid.VerticalEdges .Where(e => e.ColIndex == col && e.RowIndex == row) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } // 布置中间水平边(第1行和第2行) for (int row = 1; row < _grid.RowCount; row极 += 4) // 每4行的第1行 { for (int col = 0; col < _grid.ColumnCount; col++) { // 跳过中间列(列索引为1或2 mod 4) if (col % 4 == 1 || col % 4 == 2) continue; var edges = _极.HorizontalEdges .Where(e => e.RowIndex == row && e.ColIndex == col) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } for (int row = 2; row < _grid.RowCount; row += 4) // 每4行的第2行 { for (int col = 0; col < _grid.ColumnCount; col++) { // 跳过中间列(列索引为1或2 mod 4) if (col % 4 == 1 || col % 4 == 2) continue; var edges = _grid.HorizontalEdges .Where(e => e.RowIndex == row && e.ColIndex == col) .ToList(); foreach (var edge in edges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } } } ed.WriteMessage($"\n隔三布一模式: 删除了 {deletedCount} 根斜拉杆,布置了 {count} 根斜拉杆"); return count; } // 模式4: 满布 private int PlaceFullPattern(Database db, Transaction tr, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Editor ed, ref int processed, int totalEdges, ref int lastReported) { int count = 0; // 布置所有水平边 foreach (GridEdge edge in _grid.HorizontalEdges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } // 布置所有垂直边 foreach (GridEdge edge in _grid.VerticalEdges) { count += PlaceSingleBar(edge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } 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, ref int processed, int totalEdges, ref int lastReported) { 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, ref processed, totalEdges, ref lastReported); } // 下边 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, ref processed, totalEdges, ref lastReported); } // 左边 var leftEdge = _grid.VerticalEdges .FirstOrDefault(e => e.ColIndex == col && e.RowIndex == row); if (leftEdge != null) { count += PlaceSingleBar(leftEdge, btr, bt, placedEdges, db, tr, ed, ref processed, totalEdges, ref lastReported); } // 右边 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, ref processed, totalEdges, ref lastReported); } return count; } // 布置单根斜拉杆(优化旋转角度计算) private int PlaceSingleBar(GridEdge edge, BlockTableRecord btr, BlockTable bt, HashSet<string> placedEdges, Database db, Transaction tr, Editor ed, ref int processed, int totalEdges, ref int lastReported) { // 进度报告 if (processed - lastReported > 1000) { ed.WriteMessage($"\n布置进度: {processed}/{totalEdges} ({processed * 100.0 / totalEdges:F1}%)"); lastReported = processed; if (CheckForUserCancel(ed)) { ed.WriteMessage("\n操作已取消"); return 0; } } processed++; // 生成边唯一标识 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)"); ed.WriteMessage($"\n线段坐标: ({edge.StartPoint.X:F0},{edge.StartPoint.Y:F0}) -> ({edge.EndPoint.X:F0},{edge.EndPoint.Y:F0})"); 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 = CalculateRotationAngle(edge); // 对外侧边进行偏移处理 if (edge.IsOuterEdge) { 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); // 添加详细日志 string positionDesc = GetPositionDescription(edge); ed.WriteMessage($"\n布置: {blockName} ({edge.Length:F0}mm)({midPoint.X:F0},{midPoint.Y:F0}), " + $"位置={positionDesc}, " + $"角度={rotation * 180 / Math.PI:F0}度"); return 1; } // 计算旋转角度(优化逻辑) private double CalculateRotationAngle(GridEdge edge) { // 计算方向向量 Vector3d direction = edge.EndPoint - edge.StartPoint; // 水平边 if (edge.IsHorizontal) { // 水平边:顶部0度,底部180度 return edge.IsTopEdge ? 0.0 : Math.PI; } // 垂直边 else { // 垂直边:左侧90度,右侧270度 return edge.IsLeftEdge ? Math.PI / 2 : 3 * Math.PI / 2; } } // 获取位置描述 private string GetPositionDescription(GridEdge edge) { if (edge.IsLeftEdge) return "左侧"; if (edge.IsRightEdge) return "右侧"; if (edge.IsTopEdge) return "上方"; if (edge.IsBottomEdge) return "下方"; return "内部"; } // 获取最接近的标准长度(支持组合匹配) private double GetClosestDiagonalLength(double segmentLength) { // 精确匹配优先 foreach (double len in DiagonalBarLengths) { if (Math.Abs(len - segmentLength) < Tolerance) return len; } // 尝试组合匹配(如900=600+300) if (segmentLength > DiagonalBarLengths.Min()) { foreach (double len1 in DiagonalBarLengths) { double remaining = segmentLength - len1; if (remaining <= 0) continue; foreach (double len2 in DiagonalBarLengths) { if (Math.Abs(remaining - len2) < Tolerance) { // 返回较大的标准长度(主杆) return Math.Max(len1, len2); } } } } // 找不到精确匹配则返回最接近的 return DiagonalBarLengths .OrderBy(len => Math.Abs(len - segmentLength)) .First(); } #endregion #region 斜拉杆翻转功能 [CommandMethod("FlipDiagonals", "FD", CommandFlags.Modal)] public void FlipDiagonals() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; Editor ed = doc.Editor; try { // 提示用户选择斜拉杆 PromptSelectionOptions pso = new PromptSelectionOptions(); pso.MessageForAdding = "\n选择要翻转的斜拉杆 (框选): "; pso.AllowSubSelections = true; pso.SingleOnly = false; pso.RejectObjectsFromNonCurrentSpace = true; // 设置图层过滤器 TypedValue[] filterList = { new TypedValue((int)DxfCode.LayerName, DiagonalBarLayer) }; SelectionFilter filter = new SelectionFilter(filterList); PromptSelectionResult selResult = ed.GetSelection(pso, filter); if (selResult.Status != PromptStatus.OK) return; int flipCount = 0; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTableRecord btr = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite); foreach (SelectedObject selObj in selResult.Value) { BlockReference br = tr.GetObject(selObj.ObjectId, OpenMode.ForWrite) as BlockReference; if (br != null && br.Layer == DiagonalBarLayer) { // 获取原始方向 string originalDirection = GetDiagonalDirection(br.Rotation); // 计算翻转角度(180度) double newRotation = br.Rotation + Math.PI; // 角度归一化到0-2π范围 if (newRotation > 2 * Math.PI) newRotation -= 2 * Math.PI; // 获取新方向 string newDirection = GetDiagonalDirection(newRotation); // 应用新角度 br.Rotation = newRotation; flipCount++; // 更新日志 ed.WriteMessage($"\n翻转: {originalDirection}→{newDirection} " + $"({br.Rotation * 180 / Math.PI:F0}°→{newRotation * 180 / Math.PI:F0}°)"); } } tr.Commit(); } ed.WriteMessage($"\n成功翻转 {flipCount} 根斜拉杆"); } catch (System.Exception ex) { ed.WriteMessage($"\n翻转错误: {ex.Message}"); } } // 获取斜拉杆方向描述 private string GetDiagonalDirection(double rotation) { double degrees = rotation * 180 / Math.PI; // 简化到0-360范围 degrees %= 360; if (degrees < 0) degrees += 360; // 方向分类 if (degrees >= 315 || degrees < 45) return "上"; if (degrees >= 45 && degrees < 135) return "右"; if (degrees >= 135 && degrees < 225) return "下"; return "左"; } #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},{rounded极.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; } // 用户取消检查 private bool CheckForUserCancel(Editor ed) { try { PromptResult result = ed.GetString("\n按ESC取消操作 [按回车继续]"); return result.Status == PromptStatus.Cancel; } catch { return false; } } #endregion } } IDE1007当前上下文中不存在名称“private极”。 CS1519 Invalid token ‘const’ in a member declaration CS1009无法识别的转义序列 CS1061“Database”未包含”CurrentSpace极”的定义,并且找不到可接受第一个“Database"类型参数的可访问扩展方法“CurrentSpace极”(是否缺少using 指令或程序集引用?) CS0103当前上下文中不存在名称mid极1” CS0103当前上下文中不存在名称“x极Coords” CS1503参数2:无法从“Autodesk.AutoCAD.Geometry.Point3d”转换为“Point3极” CS0246未能找到类型或命名空间名“Point3极”(是否缺少using 指令或程序集引用?) CS0103当前上下文中不存在名称totalEdges CS0103当前上下文中不存在名称totalEdges” CS0103当前上下文中不存在名称totalEdges” CS0103当前上下文中不存在名称“row极 CS0103当前上下文中不存在名称极” CS0103当前上下文中不存在名称totalEdges” CS0103当前上下文中不存在名称totalEdges CS0103当前上下文中不存在名称rounded极
07-11
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值