diff --git a/Cad/TemplateDrawingService.cs b/Cad/TemplateDrawingService.cs index a6392cb..0970113 100644 --- a/Cad/TemplateDrawingService.cs +++ b/Cad/TemplateDrawingService.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text.RegularExpressions; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; +using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using CadParamPluging.Common; using CadParamPluging.Domain.Models; @@ -18,6 +19,13 @@ namespace CadParamPluging.Cad private static readonly Regex MTextFormatRegex = new Regex(@"\\[A-Za-z]+[^;]*;", RegexOptions.Compiled); + private static readonly Regex CaxaLayerRegex = new Regex(@"^CAXA\d$", RegexOptions.Compiled | RegexOptions.IgnoreCase); + + private static readonly HashSet DimensionLayerNames = new HashSet(StringComparer.OrdinalIgnoreCase) + { + "尺寸标注", "标注", "DIM", "DIMENSION", "DIMENSIONS" + }; + public static Document CreateDocumentFromTemplate(TemplateInfo template) { var doc = Application.DocumentManager.Add(template.FilePath); @@ -656,5 +664,253 @@ namespace CadParamPluging.Cad && a.MinPoint.Y <= b.MaxPoint.Y && a.MaxPoint.Y >= b.MinPoint.Y; } + + public sealed class RemoveOriginalDrawingResult + { + public int CaxaLayerErased { get; set; } + public int DimensionLayerErased { get; set; } + public int DimensionLayerKept { get; set; } + public Point3d OriginalCenter { get; set; } + public Extents3d? OriginalExtents { get; set; } + } + + /// + /// 删除模板中原有的图纸图形,保留右上角区域的内容(如粗糙度标注)。 + /// + /// CAD上下文 + /// 右上角保留区域阈值,0.70表示X和Y都超过70%的位置 + /// 删除结果,包含原图形中心点位置 + public static RemoveOriginalDrawingResult RemoveTemplateOriginalDrawing(CadContext ctx, double topRightThreshold = 0.70) + { + if (ctx == null) + { + throw new ArgumentNullException(nameof(ctx)); + } + + var result = new RemoveOriginalDrawingResult(); + var db = ctx.Database; + var tr = ctx.Transaction; + + var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); + var ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); + + var allEntities = ms.Cast() + .Select(id => tr.GetObject(id, OpenMode.ForRead, false) as Entity) + .Where(e => e != null) + .ToList(); + + var layoutExtents = ComputeLayoutExtents(allEntities); + var caxaExtents = ComputeCaxaLayerExtents(tr, allEntities); + + if (caxaExtents.HasValue) + { + result.OriginalExtents = caxaExtents; + result.OriginalCenter = new Point3d( + (caxaExtents.Value.MinPoint.X + caxaExtents.Value.MaxPoint.X) / 2, + (caxaExtents.Value.MinPoint.Y + caxaExtents.Value.MaxPoint.Y) / 2, + 0); + } + + // 使用CAXA图层范围作为图形区域,用于判断右上角 + var graphicExtents = caxaExtents ?? layoutExtents; + + foreach (var ent in allEntities) + { + if (ent.IsErased) + { + continue; + } + + var layerName = GetLayerName(tr, ent.LayerId); + + if (IsCaxaLayer(layerName)) + { + var entForWrite = tr.GetObject(ent.ObjectId, OpenMode.ForWrite) as Entity; + if (entForWrite != null) + { + entForWrite.Erase(true); + result.CaxaLayerErased++; + } + continue; + } + + if (IsDimensionLayer(layerName) || IsDimensionEntity(ent)) + { + // 基于CAXA图形区域判断是否在右上角 + if (graphicExtents.HasValue && IsInTopRightCorner(ent, graphicExtents.Value, topRightThreshold)) + { + result.DimensionLayerKept++; + continue; + } + + var entForWrite = tr.GetObject(ent.ObjectId, OpenMode.ForWrite) as Entity; + if (entForWrite != null) + { + entForWrite.Erase(true); + result.DimensionLayerErased++; + } + } + } + + return result; + } + + private static string GetLayerName(Transaction tr, ObjectId layerId) + { + if (layerId.IsNull) + { + return string.Empty; + } + + try + { + var layer = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord; + return layer?.Name ?? string.Empty; + } + catch + { + return string.Empty; + } + } + + private static bool IsCaxaLayer(string layerName) + { + if (string.IsNullOrWhiteSpace(layerName)) + { + return false; + } + + return CaxaLayerRegex.IsMatch(layerName); + } + + private static bool IsDimensionLayer(string layerName) + { + if (string.IsNullOrWhiteSpace(layerName)) + { + return false; + } + + return DimensionLayerNames.Contains(layerName); + } + + private static bool IsDimensionEntity(Entity ent) + { + return ent is Dimension + || ent is RotatedDimension + || ent is AlignedDimension + || ent is RadialDimension + || ent is DiametricDimension + || ent is ArcDimension + || ent is OrdinateDimension + || ent is Leader; + } + + private static Extents3d? ComputeLayoutExtents(IEnumerable entities) + { + Extents3d? result = null; + + foreach (var ent in entities) + { + if (ent == null || ent.IsErased) + { + continue; + } + + try + { + var ext = ent.GeometricExtents; + if (result == null) + { + result = ext; + } + else + { + result = new Extents3d( + new Point3d( + Math.Min(result.Value.MinPoint.X, ext.MinPoint.X), + Math.Min(result.Value.MinPoint.Y, ext.MinPoint.Y), + Math.Min(result.Value.MinPoint.Z, ext.MinPoint.Z)), + new Point3d( + Math.Max(result.Value.MaxPoint.X, ext.MaxPoint.X), + Math.Max(result.Value.MaxPoint.Y, ext.MaxPoint.Y), + Math.Max(result.Value.MaxPoint.Z, ext.MaxPoint.Z))); + } + } + catch + { + // 忽略无法获取范围的实体 + } + } + + return result; + } + + private static Extents3d? ComputeCaxaLayerExtents(Transaction tr, IEnumerable entities) + { + Extents3d? result = null; + + foreach (var ent in entities) + { + if (ent == null || ent.IsErased) + { + continue; + } + + var layerName = GetLayerName(tr, ent.LayerId); + if (!IsCaxaLayer(layerName)) + { + continue; + } + + try + { + var ext = ent.GeometricExtents; + if (result == null) + { + result = ext; + } + else + { + result = new Extents3d( + new Point3d( + Math.Min(result.Value.MinPoint.X, ext.MinPoint.X), + Math.Min(result.Value.MinPoint.Y, ext.MinPoint.Y), + Math.Min(result.Value.MinPoint.Z, ext.MinPoint.Z)), + new Point3d( + Math.Max(result.Value.MaxPoint.X, ext.MaxPoint.X), + Math.Max(result.Value.MaxPoint.Y, ext.MaxPoint.Y), + Math.Max(result.Value.MaxPoint.Z, ext.MaxPoint.Z))); + } + } + catch + { + // 忽略 + } + } + + return result; + } + + private static bool IsInTopRightCorner(Entity ent, Extents3d layoutExtents, double threshold) + { + try + { + var ext = ent.GeometricExtents; + var centerX = (ext.MinPoint.X + ext.MaxPoint.X) / 2; + var centerY = (ext.MinPoint.Y + ext.MaxPoint.Y) / 2; + + var layoutWidth = layoutExtents.MaxPoint.X - layoutExtents.MinPoint.X; + var layoutHeight = layoutExtents.MaxPoint.Y - layoutExtents.MinPoint.Y; + + var thresholdX = layoutExtents.MinPoint.X + layoutWidth * threshold; + var thresholdY = layoutExtents.MinPoint.Y + layoutHeight * threshold; + + return centerX > thresholdX && centerY > thresholdY; + } + catch + { + return true; + } + } } } diff --git a/UI/ParamDrawingPanel.cs b/UI/ParamDrawingPanel.cs index e318417..99de319 100644 --- a/UI/ParamDrawingPanel.cs +++ b/UI/ParamDrawingPanel.cs @@ -612,6 +612,10 @@ namespace CadParamPluging.UI } } + // 删除模板中原有的图纸图形(CAXA图层和尺寸标注,保留右上角) + var removeResult = TemplateDrawingService.RemoveTemplateOriginalDrawing(ctx); + AppendLog($"已删除原有图形: CAXA图层={removeResult.CaxaLayerErased}, 标注={removeResult.DimensionLayerErased}, 保留右上角={removeResult.DimensionLayerKept}"); + // 根据模板参数绘制半剖视图 HalfSectionDrawer.Draw( ctx,