using System; using System.Collections.Generic; using System.Linq; using System.Text.RegularExpressions; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using CadParamPluging.Domain.Models; namespace CadParamPluging.Cad { public static class TemplateDrawingService { private static readonly Regex MatchFieldRegex = new Regex( @"^\s*(交付状态|工艺方法|结构特征|特殊条件)\s*[::]\s*(.+?)\s*$", RegexOptions.Compiled); private static readonly Regex MTextFormatRegex = new Regex(@"\\[A-Za-z]+[^;]*;", RegexOptions.Compiled); public static Document CreateDocumentFromTemplate(TemplateInfo template) { var doc = Application.DocumentManager.Add(template.FilePath); Application.DocumentManager.MdiActiveDocument = doc; return doc; } /// /// 移除模板中用于“匹配模板/图纸”的参数标注文本(交付状态/工艺方法/结构特征/特殊条件)。 /// 仅清理当前生成图纸中目标空间(Layout 或 ModelSpace)里的文本实体/块属性。 /// public static int RemoveMatchParameterAnnotations(CadContext ctx, string layoutName, bool scanModelSpace) { if (ctx == null) { throw new ArgumentNullException(nameof(ctx)); } var db = ctx.Database; var tr = ctx.Transaction; if (scanModelSpace) { var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); var ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); return EraseMatchTextEntities(tr, ms); } if (string.IsNullOrWhiteSpace(layoutName)) { return 0; } var layoutDict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead); ObjectId layoutId = ObjectId.Null; foreach (DBDictionaryEntry entry in layoutDict) { if (string.Equals(entry.Key, layoutName, StringComparison.OrdinalIgnoreCase)) { layoutId = entry.Value; break; } } if (layoutId.IsNull) { return 0; } var layout = (Layout)tr.GetObject(layoutId, OpenMode.ForRead); var btr = (BlockTableRecord)tr.GetObject(layout.BlockTableRecordId, OpenMode.ForWrite); return EraseMatchTextEntities(tr, btr); } private static int EraseMatchTextEntities(Transaction tr, BlockTableRecord btr) { if (tr == null || btr == null) { return 0; } var removed = 0; var ids = btr.Cast().ToList(); foreach (var id in ids) { var ent = tr.GetObject(id, OpenMode.ForWrite, false) as Entity; if (ent == null) { continue; } if (ent is DBText t) { if (ContainsMatchField(t.TextString)) { ent.Erase(true); removed++; } continue; } if (ent is MText mt) { var plain = SimplifyMText(mt.Contents); if (ContainsMatchField(plain)) { ent.Erase(true); removed++; } continue; } if (ent is BlockReference br) { foreach (ObjectId attId in br.AttributeCollection) { var att = tr.GetObject(attId, OpenMode.ForWrite, false) as AttributeReference; if (att == null) { continue; } if (ContainsMatchField(att.TextString)) { try { att.Erase(true); removed++; } catch { // ignore } } } } } return removed; } private static bool ContainsMatchField(string raw) { if (string.IsNullOrWhiteSpace(raw)) { return false; } var lines = raw .Replace("\r\n", "\n") .Replace("\r", "\n") .Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries) .Select(s => (s ?? string.Empty).Trim()) .Where(s => s.Length > 0); foreach (var line in lines) { if (MatchFieldRegex.IsMatch(line)) { return true; } } return false; } private static string SimplifyMText(string contents) { if (string.IsNullOrEmpty(contents)) { return string.Empty; } var s = contents .Replace("\\P", "\n") .Replace("\\p", "\n") .Replace("\\~", " "); s = s.Replace("{", string.Empty).Replace("}", string.Empty); s = MTextFormatRegex.Replace(s, string.Empty); return s; } public static void KeepOnlyLayout(Document doc, string layoutName) { if (doc == null) { throw new ArgumentNullException(nameof(doc)); } if (string.IsNullOrWhiteSpace(layoutName)) { return; } using (doc.LockDocument()) { var db = doc.Database; var prevDb = HostApplicationServices.WorkingDatabase; HostApplicationServices.WorkingDatabase = db; try { List layoutNames; using (var tr = db.TransactionManager.StartTransaction()) { var layoutDict = (DBDictionary)tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead); layoutNames = layoutDict.Cast().Select(e => e.Key).ToList(); tr.Commit(); } if (!layoutNames.Any(n => string.Equals(n, layoutName, StringComparison.OrdinalIgnoreCase))) { return; } var lm = LayoutManager.Current; lm.CurrentLayout = layoutName; foreach (var name in layoutNames) { if (string.Equals(name, "Model", StringComparison.OrdinalIgnoreCase)) { continue; } if (string.Equals(name, layoutName, StringComparison.OrdinalIgnoreCase)) { continue; } try { lm.DeleteLayout(name); } catch { // ignore } } } finally { HostApplicationServices.WorkingDatabase = prevDb; } } } public static void KeepOnlyModelWindow(Document doc, Extents3d window) { if (doc == null) { throw new ArgumentNullException(nameof(doc)); } using (doc.LockDocument()) { var db = doc.Database; using (var tr = db.TransactionManager.StartTransaction()) { var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); var ms = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite); var erased = 0; var kept = 0; foreach (ObjectId id in ms) { var ent = tr.GetObject(id, OpenMode.ForWrite) as Entity; if (ent == null) { continue; } try { var ext = ent.GeometricExtents; if (!Intersects(ext, window)) { ent.Erase(true); erased++; } else { kept++; } } catch { // 无法获取范围的对象默认保留,避免误删关键对象 kept++; } } tr.Commit(); } } } private static bool Intersects(Extents3d a, Extents3d b) { return a.MinPoint.X <= b.MaxPoint.X && a.MaxPoint.X >= b.MinPoint.X && a.MinPoint.Y <= b.MaxPoint.Y && a.MaxPoint.Y >= b.MinPoint.Y; } } }