
大家好!在前两篇中我们学习了Teigha的读取和修改操作,今天我们来深入探讨删除操作。删除是CAD文件编辑中最危险的操作,一旦误删可能造成不可逆的数据损失。本文将用最详细的方式教你如何安全、彻底地清理DWG文件。
一、删除前的安全准备
1. 完整的备份系统
cs
public class SafeDeleteManager{ private readonly string _originalFilePath; private string _backupPath; private readonly List<string> _deletionLog = new List<string>();
public SafeDeleteManager(string filePath) { _originalFilePath = filePath; CreateBackup(); }
/// <summary> /// 创建智能备份 /// </summary> private void CreateBackup() { try { string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss"); string fileName = Path.GetFileNameWithoutExtension(_originalFilePath); string directory = Path.GetDirectoryName(_originalFilePath);
_backupPath = Path.Combine(directory, $"{fileName}_backup_{timestamp}.dwg"); File.Copy(_originalFilePath, _backupPath, true);
Console.WriteLine($"✅ 已创建备份文件: {_backupPath}"); LogAction($"创建备份: {_backupPath}"); } catch (Exception ex) { throw new Exception($"创建备份失败: {ex.Message}"); } }
/// <summary> /// 执行安全删除操作 /// </summary> public bool ExecuteSafeDelete(Action<Database, Transaction> deleteAction) { try { using (Services services = new Services()) using (Database db = new Database(false, true)) { db.ReadDwgFile(_originalFilePath, FileShare.ReadWrite, true, "");
using (Transaction tr = db.TransactionManager.StartTransaction()) { // 记录删除前的状态 RecordPreDeletionState(db, tr);
// 执行删除操作 deleteAction(db, tr);
tr.Commit(); }
// 验证删除结果 if (ValidateDeletion(db)) { db.SaveAs(_originalFilePath, DwgVersion.Current); Console.WriteLine("✅ 删除操作完成并已保存"); SaveDeletionLog(); return true; } else { RestoreBackup(); Console.WriteLine("❌ 删除验证失败,已恢复备份"); return false; } } } catch (Exception ex) { RestoreBackup(); Console.WriteLine($"❌ 删除操作失败,已恢复备份: {ex.Message}"); return false; } }
/// <summary> /// 记录删除前的状态 /// </summary> private void RecordPreDeletionState(Database db, Transaction tr) { LogAction("=== 删除前状态记录 ===");
// 记录图层信息 LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); LogAction($"图层数量: {layerTable.Count}");
// 记录块信息 BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); LogAction($"块定义数量: {blockTable.Count}");
// 记录模型空间实体数量 BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject( blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead); LogAction($"模型空间实体数量: {modelSpace.Count}"); }
/// <summary> /// 验证删除结果 /// </summary> private bool ValidateDeletion(Database db) { using (Transaction tr = db.TransactionManager.StartTransaction()) { try { // 检查数据库完整性 LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// 基本验证:确保还有图层和模型空间 if (layerTable.Count == 0) { LogAction("❌ 验证失败:所有图层已被删除"); return false; }
if (!blockTable.Has(BlockTableRecord.ModelSpace)) { LogAction("❌ 验证失败:模型空间不存在"); return false; }
LogAction("✅ 删除验证通过"); return true; } catch (Exception ex) { LogAction($"❌ 验证过程中出错: {ex.Message}"); return false; } } }
/// <summary> /// 恢复备份 /// </summary> private void RestoreBackup() { try { if (File.Exists(_backupPath)) { File.Copy(_backupPath, _originalFilePath, true); LogAction($"已从备份恢复: {_backupPath}"); } } catch (Exception ex) { LogAction($"恢复备份失败: {ex.Message}"); } }
/// <summary> /// 记录操作日志 /// </summary> private void LogAction(string message) { string timestamp = DateTime.Now.ToString("HH:mm:ss"); string logEntry = $"[{timestamp}] {message}"; _deletionLog.Add(logEntry); Console.WriteLine(logEntry); }
/// <summary> /// 保存删除日志 /// </summary> private void SaveDeletionLog() { try { string logPath = Path.ChangeExtension(_originalFilePath, ".deletion.log"); File.WriteAllLines(logPath, _deletionLog); Console.WriteLine($"✅ 删除日志已保存: {logPath}"); } catch (Exception ex) { Console.WriteLine($"❌ 保存删除日志失败: {ex.Message}"); } }
/// <summary> /// 清理备份文件(可选) /// </summary> public void CleanupBackup() { try { if (File.Exists(_backupPath)) { File.Delete(_backupPath); Console.WriteLine($"✅ 备份文件已清理: {_backupPath}"); } } catch (Exception ex) { Console.WriteLine($"清理备份文件失败: {ex.Message}"); } }}
二、图层删除详解
1. 安全图层删除器
cs
public class LayerDeletionManager{ /// <summary> /// 安全删除图层(带完整验证) /// </summary> public static DeletionResult DeleteLayerSafely(Database db, Transaction tr, string layerName) { var result = new DeletionResult();
try { LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForWrite);
// 验证图层是否存在 if (!layerTable.Has(layerName)) { result.Success = false; result.Message = $"图层 '{layerName}' 不存在"; return result; }
ObjectId layerId = layerTable[layerName]; LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
// 验证是否为系统图层 if (IsSystemLayer(layer.Name)) { result.Success = false; result.Message = $"不能删除系统图层 '{layer.Name}'"; return result; }
// 检查图层使用情况 var usageInfo = CheckLayerUsage(db, tr, layerId); if (usageInfo.IsUsed) { result.Success = false; result.Message = $"图层 '{layerName}' 正在被使用,无法删除"; result.Details = usageInfo; return result; }
// 执行删除 layer.UpgradeOpen(); layer.Erase();
result.Success = true; result.Message = $"成功删除图层: {layerName}"; result.DeletedObjectId = layerId;
return result; } catch (Exception ex) { result.Success = false; result.Message = $"删除图层失败: {ex.Message}"; return result; } }
/// <summary> /// 检查系统图层 /// </summary> private static bool IsSystemLayer(string layerName) { string[] systemLayers = { "0", // 默认图层 "DEFPOINTS", // 定义点图层 "ASHADE", // 阴影图层 "A$C*" // AutoCAD临时图层 };
return systemLayers.Any(systemLayer => systemLayer.Contains('*') ? System.Text.RegularExpressions.Regex.IsMatch(layerName, systemLayer.Replace("*", ".*")) : systemLayer.Equals(layerName, StringComparison.OrdinalIgnoreCase)); }
/// <summary> /// 详细检查图层使用情况 /// </summary> private static LayerUsageInfo CheckLayerUsage(Database db, Transaction tr, ObjectId layerId) { var usageInfo = new LayerUsageInfo();
BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId blockId in blockTable) { BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead); string blockType = GetBlockType(block);
foreach (ObjectId entityId in block) { Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity; if (entity != null && entity.LayerId == layerId) { usageInfo.IsUsed = true; usageInfo.UsedInBlocks.Add(block.Name); usageInfo.EntityCount++; usageInfo.EntityTypes.Add(entity.GetType().Name);
// 记录具体使用情况 usageInfo.UsageDetails.Add(new EntityUsage { BlockName = block.Name, BlockType = blockType, EntityType = entity.GetType().Name, EntityId = entityId }); } } }
return usageInfo; }
/// <summary> /// 获取块类型描述 /// </summary> private static string GetBlockType(BlockTableRecord block) { if (block.Name == BlockTableRecord.ModelSpace) return "模型空间"; else if (block.Name.StartsWith(BlockTableRecord.PaperSpace)) return "图纸空间"; else if (block.IsAnonymous) return "匿名块"; else return "普通块"; }
/// <summary> /// 强制删除图层(包括其中的实体) /// </summary> public static DeletionResult ForceDeleteLayer(Database db, Transaction tr, string layerName) { var result = new DeletionResult();
try { LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForWrite);
if (!layerTable.Has(layerName)) { result.Success = false; result.Message = $"图层 '{layerName}' 不存在"; return result; }
ObjectId layerId = layerTable[layerName];
// 先删除图层中的所有实体 var deletionStats = DeleteAllEntitiesInLayer(db, tr, layerId);
// 然后删除图层本身 LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForWrite); layer.Erase();
result.Success = true; result.Message = $"强制删除图层完成: {layerName}"; result.Details = deletionStats; result.DeletedObjectId = layerId;
return result; } catch (Exception ex) { result.Success = false; result.Message = $"强制删除图层失败: {ex.Message}"; return result; } }
/// <summary> /// 删除图层中的所有实体 /// </summary> private static LayerDeletionStats DeleteAllEntitiesInLayer(Database db, Transaction tr, ObjectId layerId) { var stats = new LayerDeletionStats();
BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId blockId in blockTable) { BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForWrite);
// 收集要删除的实体 var entitiesToDelete = new List<ObjectId>(); foreach (ObjectId entityId in block) { Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity; if (entity != null && entity.LayerId == layerId) { entitiesToDelete.Add(entityId); } }
// 执行删除 foreach (ObjectId entityId in entitiesToDelete) { Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity; string entityType = entity.GetType().Name;
entity.Erase(); stats.DeletedEntityCount++;
if (stats.EntityTypeCounts.ContainsKey(entityType)) stats.EntityTypeCounts[entityType]++; else stats.EntityTypeCounts[entityType] = 1;
stats.BlocksAffected.Add(block.Name); } }
stats.BlocksAffected = stats.BlocksAffected.Distinct().ToList(); return stats; }
/// <summary> /// 批量删除空图层 /// </summary> public static BatchDeletionResult DeleteEmptyLayers(Database db, Transaction tr) { var result = new BatchDeletionResult();
try { LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForWrite); var emptyLayers = new List<string>();
foreach (ObjectId layerId in layerTable) { LayerTableRecord layer = (LayerTableRecord)tr.GetObject(layerId, OpenMode.ForRead);
// 跳过系统图层 if (IsSystemLayer(layer.Name)) continue;
// 检查图层是否为空 if (!IsLayerUsed(db, tr, layerId)) { emptyLayers.Add(layer.Name); } }
// 删除空图层 foreach (string layerName in emptyLayers) { var deletionResult = DeleteLayerSafely(db, tr, layerName); if (deletionResult.Success) { result.SuccessfulDeletions++; result.DeletedItems.Add(layerName); } else { result.FailedDeletions++; result.Errors.Add($"{layerName}: {deletionResult.Message}"); } }
result.TotalProcessed = emptyLayers.Count; return result; } catch (Exception ex) { result.Success = false; result.Message = $"批量删除空图层失败: {ex.Message}"; return result; } }
/// <summary> /// 简化版图层使用检查 /// </summary> private static bool IsLayerUsed(Database db, Transaction tr, ObjectId layerId) { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId blockId in blockTable) { BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
foreach (ObjectId entityId in block) { Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity; if (entity != null && entity.LayerId == layerId) { return true; } } }
return false; }}
// 删除结果类public class DeletionResult{ public bool Success { get; set; } public string Message { get; set; } public ObjectId DeletedObjectId { get; set; } public object Details { get; set; }}
// 图层使用信息public class LayerUsageInfo{ public bool IsUsed { get; set; } public int EntityCount { get; set; } public List<string> UsedInBlocks { get; set; } = new List<string>(); public List<string> EntityTypes { get; set; } = new List<string>(); public List<EntityUsage> UsageDetails { get; set; } = new List<EntityUsage>();}
public class EntityUsage{ public string BlockName { get; set; } public string BlockType { get; set; } public string EntityType { get; set; } public ObjectId EntityId { get; set; }}
// 图层删除统计public class LayerDeletionStats{ public int DeletedEntityCount { get; set; } public Dictionary<string, int> EntityTypeCounts { get; set; } = new Dictionary<string, int>(); public List<string> BlocksAffected { get; set; } = new List<string>();}
// 批量删除结果public class BatchDeletionResult{ public bool Success { get; set; } = true; public string Message { get; set; } public int TotalProcessed { get; set; } public int SuccessfulDeletions { get; set; } public int FailedDeletions { get; set; } public List<string> DeletedItems { get; set; } = new List<string>(); public List<string> Errors { get; set; } = new List<string>();}
三、实体删除详解
1. 实体删除管理器
cs
public class EntityDeletionManager{ /// <summary> /// 按类型删除实体 /// </summary> public static EntityDeletionResult DeleteEntitiesByType(Database db, Transaction tr, Type entityType, string specificBlock = null) { var result = new EntityDeletionResult { TargetType = entityType.Name };
try { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId blockId in blockTable) { BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
// 如果指定了特定块,只处理该块 if (!string.IsNullOrEmpty(specificBlock) && block.Name != specificBlock) continue;
// 收集要删除的实体 var entitiesToDelete = new List<ObjectId>(); foreach (ObjectId entityId in block) { Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity; if (entity != null && entity.GetType() == entityType) { entitiesToDelete.Add(entityId); } }
// 执行删除 if (entitiesToDelete.Count > 0) { block.UpgradeOpen();
foreach (ObjectId entityId in entitiesToDelete) { Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity; string layerName = GetLayerName(db, tr, entity.LayerId);
entity.Erase(); result.DeletedCount++;
// 记录删除详情 result.DeletionDetails.Add(new EntityDeletionDetail { EntityId = entityId, EntityType = entityType.Name, BlockName = block.Name, LayerName = layerName, DeletionTime = DateTime.Now }); }
result.AffectedBlocks.Add(block.Name); } }
result.Success = true; result.Message = $"成功删除 {result.DeletedCount} 个 {entityType.Name} 实体";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"按类型删除实体失败: {ex.Message}"; return result; } }
/// <summary> /// 按条件删除实体 /// </summary> public static EntityDeletionResult DeleteEntitiesByCondition(Database db, Transaction tr, Func<Entity, bool> condition, string conditionDescription = "自定义条件") { var result = new EntityDeletionResult { TargetType = conditionDescription };
try { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId blockId in blockTable) { BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
// 收集要删除的实体 var entitiesToDelete = new List<ObjectId>(); foreach (ObjectId entityId in block) { Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity; if (entity != null && condition(entity)) { entitiesToDelete.Add(entityId); } }
// 执行删除 if (entitiesToDelete.Count > 0) { block.UpgradeOpen();
foreach (ObjectId entityId in entitiesToDelete) { Entity entity = tr.GetObject(entityId, OpenMode.ForWrite) as Entity; entity.Erase(); result.DeletedCount++;
result.DeletionDetails.Add(new EntityDeletionDetail { EntityId = entityId, EntityType = entity.GetType().Name, BlockName = block.Name, LayerName = GetLayerName(db, tr, entity.LayerId), DeletionTime = DateTime.Now }); }
result.AffectedBlocks.Add(block.Name); } }
result.Success = true; result.Message = $"根据条件 '{conditionDescription}' 删除了 {result.DeletedCount} 个实体";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"按条件删除实体失败: {ex.Message}"; return result; } }
/// <summary> /// 删除短直线(按长度) /// </summary> public static EntityDeletionResult DeleteShortLines(Database db, Transaction tr, double minLength) { return DeleteEntitiesByCondition(db, tr, entity => entity is Line line && line.Length < minLength, $"短直线(长度<{minLength})"); }
/// <summary> /// 删除小圆(按半径) /// </summary> public static EntityDeletionResult DeleteSmallCircles(Database db, Transaction tr, double minRadius) { return DeleteEntitiesByCondition(db, tr, entity => entity is Circle circle && circle.Radius < minRadius, $"小圆(半径<{minRadius})"); }
/// <summary> /// 删除特定图层上的实体 /// </summary> public static EntityDeletionResult DeleteEntitiesByLayer(Database db, Transaction tr, string layerName) { ObjectId layerId = GetLayerId(db, tr, layerName); if (layerId.IsNull) { return new EntityDeletionResult { Success = false, Message = $"图层 '{layerName}' 不存在", TargetType = $"图层 '{layerName}' 上的实体" }; }
return DeleteEntitiesByCondition(db, tr, entity => entity.LayerId == layerId, $"图层 '{layerName}' 上的实体"); }
/// <summary> /// 删除重复实体(基于位置和类型) /// </summary> public static EntityDeletionResult DeleteDuplicateEntities(Database db, Transaction tr, double tolerance = 0.001) { var result = new EntityDeletionResult { TargetType = "重复实体" };
try { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject( blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead);
// 收集所有实体及其位置信息 var entityPositions = new Dictionary<string, List<ObjectId>>();
foreach (ObjectId entityId in modelSpace) { Entity entity = tr.GetObject(entityId, OpenMode.ForRead) as Entity; if (entity != null) { string positionKey = GetEntityPositionKey(entity, tolerance); if (!string.IsNullOrEmpty(positionKey)) { if (!entityPositions.ContainsKey(positionKey)) entityPositions[positionKey] = new List<ObjectId>();
entityPositions[positionKey].Add(entityId); } } }
// 删除重复实体(每个位置只保留一个) modelSpace.UpgradeOpen();
foreach (var kvp in entityPositions) { if (kvp.Value.Count > 1) { // 保留第一个,删除其余的 for (int i = 1; i < kvp.Value.Count; i++) { Entity entity = tr.GetObject(kvp.Value[i], OpenMode.ForWrite) as Entity; entity.Erase(); result.DeletedCount++;
result.DeletionDetails.Add(new EntityDeletionDetail { EntityId = kvp.Value[i], EntityType = entity.GetType().Name, BlockName = "ModelSpace", LayerName = GetLayerName(db, tr, entity.LayerId), DeletionTime = DateTime.Now, Notes = "重复实体" }); }
result.AffectedBlocks.Add("ModelSpace"); } }
result.Success = true; result.Message = $"删除了 {result.DeletedCount} 个重复实体";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"删除重复实体失败: {ex.Message}"; return result; } }
/// <summary> /// 获取实体位置键(用于重复检测) /// </summary> private static string GetEntityPositionKey(Entity entity, double tolerance) { switch (entity) { case Line line: return $"Line_{Math.Round(line.StartPoint.X / tolerance)}_{Math.Round(line.StartPoint.Y / tolerance)}_{Math.Round(line.EndPoint.X / tolerance)}_{Math.Round(line.EndPoint.Y / tolerance)}";
case Circle circle: return $"Circle_{Math.Round(circle.Center.X / tolerance)}_{Math.Round(circle.Center.Y / tolerance)}_{Math.Round(circle.Radius / tolerance)}";
case DBText text: return $"Text_{Math.Round(text.Position.X / tolerance)}_{Math.Round(text.Position.Y / tolerance)}_{text.TextString}";
case BlockReference blockRef: return $"Block_{blockRef.Name}_{Math.Round(blockRef.Position.X / tolerance)}_{Math.Round(blockRef.Position.Y / tolerance)}";
default: return null; } }
/// <summary> /// 获取图层ID /// </summary> private static ObjectId GetLayerId(Database db, Transaction tr, string layerName) { LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); return layerTable.Has(layerName) ? layerTable[layerName] : ObjectId.Null; }
/// <summary> /// 获取图层名称 /// </summary> private static string GetLayerName(Database db, Transaction tr, ObjectId layerId) { if (layerId.IsValid && !layerId.IsNull) { LayerTableRecord layer = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord; return layer?.Name ?? "未知图层"; } return "无图层"; }}
// 实体删除结果public class EntityDeletionResult{ public bool Success { get; set; } public string Message { get; set; } public string TargetType { get; set; } public int DeletedCount { get; set; } public List<string> AffectedBlocks { get; set; } = new List<string>(); public List<EntityDeletionDetail> DeletionDetails { get; set; } = new List<EntityDeletionDetail>();}
public class EntityDeletionDetail{ public ObjectId EntityId { get; set; } public string EntityType { get; set; } public string BlockName { get; set; } public string LayerName { get; set; } public DateTime DeletionTime { get; set; } public string Notes { get; set; }}
四、块定义删除详解
1. 块定义删除管理器
cs
public class BlockDeletionManager{ /// <summary> /// 删除未使用的块定义 /// </summary> public static BlockDeletionResult DeleteUnusedBlocks(Database db, Transaction tr) { var result = new BlockDeletionResult();
try { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite); var unusedBlocks = new List<BlockTableRecord>();
// 查找未使用的块 foreach (ObjectId blockId in blockTable) { BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
// 跳过系统块 if (IsSystemBlock(block)) continue;
// 检查块是否被引用 if (!IsBlockReferenced(db, tr, blockId)) { unusedBlocks.Add(block); } }
// 删除未使用的块 foreach (BlockTableRecord block in unusedBlocks) { try { block.UpgradeOpen(); string blockName = block.Name; block.Erase();
result.DeletedBlocks.Add(blockName); result.SuccessfulDeletions++;
Console.WriteLine($"✅ 删除未使用的块: {blockName}"); } catch (Exception ex) { result.FailedDeletions++; result.Errors.Add($"删除块 '{block.Name}' 失败: {ex.Message}"); } }
result.TotalProcessed = unusedBlocks.Count; result.Success = true; result.Message = $"删除了 {result.SuccessfulDeletions} 个未使用的块定义";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"删除未使用块失败: {ex.Message}"; return result; } }
/// <summary> /// 检查系统块 /// </summary> private static bool IsSystemBlock(BlockTableRecord block) { string[] systemBlocks = { BlockTableRecord.ModelSpace, BlockTableRecord.PaperSpace, "*Model_Space", "*Paper_Space" };
return systemBlocks.Contains(block.Name) || block.IsAnonymous || block.Name.StartsWith("*"); }
/// <summary> /// 检查块是否被引用 /// </summary> private static bool IsBlockReferenced(Database db, Transaction tr, ObjectId blockId) { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId spaceId in blockTable) { BlockTableRecord space = (BlockTableRecord)tr.GetObject(spaceId, OpenMode.ForRead);
foreach (ObjectId entityId in space) { if (entity is BlockReference blockRef && blockRef.BlockTableRecord == blockId) { return true; } } }
return false; }
/// <summary> /// 删除指定的块定义 /// </summary> public static BlockDeletionResult DeleteSpecificBlock(Database db, Transaction tr, string blockName) { var result = new BlockDeletionResult();
try { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
if (!blockTable.Has(blockName)) { result.Success = false; result.Message = $"块定义 '{blockName}' 不存在"; return result; }
ObjectId blockId = blockTable[blockName]; BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForRead);
// 检查是否为系统块 if (IsSystemBlock(block)) { result.Success = false; result.Message = $"不能删除系统块 '{blockName}'"; return result; }
// 检查块是否被引用 if (IsBlockReferenced(db, tr, blockId)) { result.Success = false; result.Message = $"块 '{blockName}' 正在被使用,无法删除"; return result; }
// 执行删除 block.UpgradeOpen(); block.Erase();
result.Success = true; result.Message = $"成功删除块定义: {blockName}"; result.DeletedBlocks.Add(blockName); result.SuccessfulDeletions = 1; result.TotalProcessed = 1;
return result; } catch (Exception ex) { result.Success = false; result.Message = $"删除块定义失败: {ex.Message}"; return result; } }
/// <summary> /// 强制删除块定义(包括所有引用) /// </summary> public static BlockDeletionResult ForceDeleteBlock(Database db, Transaction tr, string blockName) { var result = new BlockDeletionResult();
try { BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
if (!blockTable.Has(blockName)) { result.Success = false; result.Message = $"块定义 '{blockName}' 不存在"; return result; }
ObjectId blockId = blockTable[blockName];
// 先删除所有块引用 var referenceDeletion = DeleteAllBlockReferences(db, tr, blockId);
// 然后删除块定义 BlockTableRecord block = (BlockTableRecord)tr.GetObject(blockId, OpenMode.ForWrite); block.Erase();
result.Success = true; result.Message = $"强制删除块完成: {blockName}"; result.DeletedBlocks.Add(blockName); result.SuccessfulDeletions = 1; result.TotalProcessed = 1; result.Details = referenceDeletion;
return result; } catch (Exception ex) { result.Success = false; result.Message = $"强制删除块失败: {ex.Message}"; return result; } }
/// <summary> /// 删除所有块引用 /// </summary> private static BlockReferenceDeletionStats DeleteAllBlockReferences(Database db, Transaction tr, ObjectId blockId) { var stats = new BlockReferenceDeletionStats();
BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
foreach (ObjectId spaceId in blockTable) { BlockTableRecord space = (BlockTableRecord)tr.GetObject(spaceId, OpenMode.ForWrite);
// 收集要删除的块引用 var referencesToDelete = new List<ObjectId>(); foreach (ObjectId entityId in space) { if (entity is BlockReference blockRef && blockRef.BlockTableRecord == blockId) { referencesToDelete.Add(entityId); } }
// 执行删除 foreach (ObjectId refId in referencesToDelete) { BlockReference blockRef = (BlockReference)tr.GetObject(refId, OpenMode.ForWrite); string layerName = GetLayerName(db, tr, blockRef.LayerId);
blockRef.Erase(); stats.DeletedReferenceCount++;
stats.DeletionDetails.Add(new BlockReferenceDeletionDetail { BlockName = blockRef.Name, LayerName = layerName, Position = blockRef.Position, DeletionTime = DateTime.Now }); } }
return stats; }
/// <summary> /// 获取图层名称 /// </summary> private static string GetLayerName(Database db, Transaction tr, ObjectId layerId) { if (layerId.IsValid && !layerId.IsNull) { LayerTableRecord layer = tr.GetObject(layerId, OpenMode.ForRead) as LayerTableRecord; return layer?.Name ?? "未知图层"; } return "无图层"; }}
// 块删除结果public class BlockDeletionResult{ public bool Success { get; set; } public string Message { get; set; } public int TotalProcessed { get; set; } public int SuccessfulDeletions { get; set; } public int FailedDeletions { get; set; } public List<string> DeletedBlocks { get; set; } = new List<string>(); public List<string> Errors { get; set; } = new List<string>(); public object Details { get; set; }}
// 块引用删除统计public class BlockReferenceDeletionStats{ public int DeletedReferenceCount { get; set; } public List<BlockReferenceDeletionDetail> DeletionDetails { get; set; } = new List<BlockReferenceDeletionDetail>();}
public class BlockReferenceDeletionDetail{ public string BlockName { get; set; } public string LayerName { get; set; } public Point3d Position { get; set; } public DateTime DeletionTime { get; set; }}
五、批量删除和清理工具
1. 综合清理工具
cs
public class ComprehensiveCleaner{ /// <summary> /// 执行全面清理 /// </summary> public static CleanupResult PerformComprehensiveCleanup(Database db, Transaction tr) { var result = new CleanupResult();
try { Console.WriteLine("开始全面清理...");
// 1. 删除未使用的块定义 Console.WriteLine("1. 清理未使用的块定义..."); var blockResult = BlockDeletionManager.DeleteUnusedBlocks(db, tr); result.BlockCleanup = blockResult;
// 2. 删除空图层 Console.WriteLine("2. 清理空图层..."); var layerResult = LayerDeletionManager.DeleteEmptyLayers(db, tr); result.LayerCleanup = layerResult;
// 3. 删除重复实体 Console.WriteLine("3. 清理重复实体..."); var duplicateResult = EntityDeletionManager.DeleteDuplicateEntities(db, tr); result.DuplicateCleanup = duplicateResult;
// 4. 清理废弃对象 Console.WriteLine("4. 清理废弃对象..."); var purgeResult = PurgeDatabase(db); result.PurgeResult = purgeResult;
result.Success = true; result.Message = "全面清理完成";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"全面清理失败: {ex.Message}"; return result; } }
/// <summary> /// 清理数据库废弃对象 /// </summary> private static PurgeResult PurgeDatabase(Database db) { var result = new PurgeResult();
try { // 记录清理前状态 using (Transaction tr = db.TransactionManager.StartTransaction()) { result.BeforePurgeStats = GetDatabaseStats(db, tr); tr.Commit(); }
// 执行清理 db.Purge(null);
// 记录清理后状态 using (Transaction tr = db.TransactionManager.StartTransaction()) { result.AfterPurgeStats = GetDatabaseStats(db, tr); tr.Commit(); }
result.Success = true; result.Message = "数据库清理完成";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"数据库清理失败: {ex.Message}"; return result; } }
/// <summary> /// 获取数据库统计信息 /// </summary> private static DatabaseStats GetDatabaseStats(Database db, Transaction tr) { var stats = new DatabaseStats();
// 图层统计 LayerTable layerTable = (LayerTable)tr.GetObject(db.LayerTableId, OpenMode.ForRead); stats.LayerCount = layerTable.Count;
// 块统计 BlockTable blockTable = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead); stats.BlockCount = blockTable.Count;
// 实体统计 BlockTableRecord modelSpace = (BlockTableRecord)tr.GetObject( blockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead); stats.ModelSpaceEntityCount = modelSpace.Count;
// 线型统计 LinetypeTable linetypeTable = (LinetypeTable)tr.GetObject(db.LinetypeTableId, OpenMode.ForRead); stats.LinetypeCount = linetypeTable.Count;
// 文字样式统计 TextStyleTable textStyleTable = (TextStyleTable)tr.GetObject(db.TextStyleTableId, OpenMode.ForRead); stats.TextStyleCount = textStyleTable.Count;
return stats; }
/// <summary> /// 按条件批量删除 /// </summary> public static BatchCleanupResult BatchDeleteByConditions(Database db, Transaction tr, CleanupConditions conditions) { var result = new BatchCleanupResult();
try { if (conditions.DeleteShortLines) { Console.WriteLine("删除短直线..."); var lineResult = EntityDeletionManager.DeleteShortLines(db, tr, conditions.ShortLineLength); result.ShortLineCleanup = lineResult; }
if (conditions.DeleteSmallCircles) { Console.WriteLine("删除小圆..."); var circleResult = EntityDeletionManager.DeleteSmallCircles(db, tr, conditions.SmallCircleRadius); result.SmallCircleCleanup = circleResult; }
if (conditions.DeleteEmptyLayers) { Console.WriteLine("删除空图层..."); var layerResult = LayerDeletionManager.DeleteEmptyLayers(db, tr); result.EmptyLayerCleanup = layerResult; }
if (conditions.DeleteUnusedBlocks) { Console.WriteLine("删除未使用的块..."); var blockResult = BlockDeletionManager.DeleteUnusedBlocks(db, tr); result.UnusedBlockCleanup = blockResult; }
if (conditions.DeleteDuplicateEntities) { Console.WriteLine("删除重复实体..."); var duplicateResult = EntityDeletionManager.DeleteDuplicateEntities(db, tr, conditions.DuplicateTolerance); result.DuplicateCleanup = duplicateResult; }
result.Success = true; result.Message = "批量删除完成";
return result; } catch (Exception ex) { result.Success = false; result.Message = $"批量删除失败: {ex.Message}"; return result; } }}
// 清理结果类public class CleanupResult{ public bool Success { get; set; } public string Message { get; set; } public BlockDeletionResult BlockCleanup { get; set; } public BatchDeletionResult LayerCleanup { get; set; } public EntityDeletionResult DuplicateCleanup { get; set; } public PurgeResult PurgeResult { get; set; }}
public class PurgeResult{ public bool Success { get; set; } public string Message { get; set; } public DatabaseStats BeforePurgeStats { get; set; } public DatabaseStats AfterPurgeStats { get; set; }}
public class DatabaseStats{ public int LayerCount { get; set; } public int BlockCount { get; set; } public int ModelSpaceEntityCount { get; set; } public int LinetypeCount { get; set; } public int TextStyleCount { get; set; }}
public class BatchCleanupResult{ public bool Success { get; set; } public string Message { get; set; } public EntityDeletionResult ShortLineCleanup { get; set; } public EntityDeletionResult SmallCircleCleanup { get; set; } public BatchDeletionResult EmptyLayerCleanup { get; set; } public BlockDeletionResult UnusedBlockCleanup { get; set; } public EntityDeletionResult DuplicateCleanup { get; set; }}
public class CleanupConditions{ public bool DeleteShortLines { get; set; } public double ShortLineLength { get; set; } = 1.0;
public bool DeleteSmallCircles { get; set; } public double SmallCircleRadius { get; set; } = 0.5;
public bool DeleteEmptyLayers { get; set; } public bool DeleteUnusedBlocks { get; set; } public bool DeleteDuplicateEntities { get; set; } public double DuplicateTolerance { get; set; } = 0.001;}
通过这篇详细的删除操作教程,你现在应该能够:
✅ 安全地进行DWG文件删除操作
✅ 删除图层、实体和块定义
✅ 使用批量删除和清理功能
✅ 通过交互式工具进行删除
✅ 处理删除过程中的错误和异常
记住,删除操作是不可逆的,一定要谨慎操作,并确保有备份!下一篇我们将学习如何向DWG文件中添加新内容。
|---------------------------------------------------------------------------------|---------------------------------------------------------------------------------|
|
|
|