现在可以删除原来模板中图纸的部分了

This commit is contained in:
sladro 2025-12-18 11:10:10 +08:00
parent f120d2e34b
commit 0efa86309d
2 changed files with 260 additions and 0 deletions

View File

@ -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<string> DimensionLayerNames = new HashSet<string>(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; }
}
/// <summary>
/// 删除模板中原有的图纸图形,保留右上角区域的内容(如粗糙度标注)。
/// </summary>
/// <param name="ctx">CAD上下文</param>
/// <param name="topRightThreshold">右上角保留区域阈值0.70表示X和Y都超过70%的位置</param>
/// <returns>删除结果,包含原图形中心点位置</returns>
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<ObjectId>()
.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<Entity> 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<Entity> 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;
}
}
}
}

View File

@ -612,6 +612,10 @@ namespace CadParamPluging.UI
}
}
// 删除模板中原有的图纸图形CAXA图层和尺寸标注保留右上角
var removeResult = TemplateDrawingService.RemoveTemplateOriginalDrawing(ctx);
AppendLog($"已删除原有图形: CAXA图层={removeResult.CaxaLayerErased}, 标注={removeResult.DimensionLayerErased}, 保留右上角={removeResult.DimensionLayerKept}");
// 根据模板参数绘制半剖视图
HalfSectionDrawer.Draw(
ctx,