AutoCAD .NET API(C#)合并DXF块问题:丢失原块结构与颜色
解决AutoCAD .NET合并块丢失结构与颜色的问题
问题根源
- 块结构丢失:原代码直接提取块内实体复制到新块,未保留原块的嵌套引用关系,应通过创建
BlockReference插入原块来保留结构 - 颜色丢失:浅克隆未完整复制实体特性,且未处理图层、线型等依赖资源;部分实体颜色继承自图层,需确保属性正确传递
- 错误遍历特殊空间:原代码遍历所有
BlockTableRecord,包含模型空间、布局空间等系统空间,导致冗余或错误实体
修正后的代码
using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Geometry; namespace CombineBlockTableRecords { public class Commands { [CommandMethod("CombineBlocks")] public void CombineBlocks() { Document doc = Application.DocumentManager.MdiActiveDocument; Database db = doc.Database; using (Transaction tr = db.TransactionManager.StartTransaction()) { BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable; BlockTableRecord modelSpace = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord; // 创建新块定义 BlockTableRecord newBlockDef = new BlockTableRecord(); newBlockDef.Name = "CombinedBlock"; newBlockDef.Origin = Point3d.Origin; bt.UpgradeOpen(); ObjectId newBlockDefId = bt.Add(newBlockDef); tr.AddNewlyCreatedDBObject(newBlockDef, true); // 1. 处理所有用户自定义块:创建BlockReference插入新块,保留嵌套结构 foreach (ObjectId btrId in bt) { BlockTableRecord btr = tr.GetObject(btrId, OpenMode.ForRead) as BlockTableRecord; // 排除新块、模型空间、布局空间和匿名块 if (btrId == newBlockDefId || btr.IsLayout || btr.IsAnonymous) continue; // 创建原块的引用并插入新块 BlockReference br = new BlockReference(Point3d.Origin, btrId); newBlockDef.AppendEntity(br); tr.AddNewlyCreatedDBObject(br, true); } // 2. 处理模型空间中的原始实体:复制并保留所有特性 foreach (ObjectId entId in modelSpace) { Entity ent = tr.GetObject(entId, OpenMode.ForRead) as Entity; // 跳过新块的引用(避免后续重复处理) if (ent is BlockReference br && br.BlockTableRecord == newBlockDefId) continue; // 深克隆实体并完整复制属性 Entity entCopy = ent.Clone() as Entity; ent.CopyPropertiesTo(entCopy); entCopy.Color = ent.Color; newBlockDef.AppendEntity(entCopy); tr.AddNewlyCreatedDBObject(entCopy, true); } // 3. 可选:清空模型空间并插入新块的引用,实现整体嵌套替换 modelSpace.UpgradeOpen(); foreach (ObjectId entId in modelSpace) { Entity ent = tr.GetObject(entId, OpenMode.ForWrite) as Entity; ent.Erase(); } BlockReference newBlockRef = new BlockReference(Point3d.Origin, newBlockDefId); modelSpace.AppendEntity(newBlockRef); tr.AddNewlyCreatedDBObject(newBlockRef, true); tr.Commit(); } } } }
关键改动说明
- 保留块嵌套结构:遍历用户自定义块时,创建
BlockReference插入到新块中,而非直接复制块内实体,完整保留原块的层级关系 - 完整保留实体特性:使用
CopyPropertiesTo复制实体的所有属性,显式同步颜色值,确保颜色、线型等属性不丢失 - 过滤无效空间:排除模型空间、布局空间、匿名块和新创建的块,避免冗余操作和错误
- 整合模型空间实体:将模型空间中的原始实体也纳入新块,并可选清空原空间插入新块引用,实现所有内容的统一嵌套
内容的提问来源于stack exchange,提问作者Guitar123
相关产品推荐
相关产品推荐

