一.概念
块定义与块参照两个概念
块定义类似于模具,而块参照类似于模具浇筑出来的模型,在图形中只需用块定义来保存块的实际几何组成,而仅用插入点和比例因子来存储块定义,因为块参照的几何形状与快参照完全一样,仅大小不同,
好处
不需要存储块参照中的实体,减小了图形文件;只需要修改块定义,块参照会自动更新,减轻了修改和维护工作。
插入一个普通块实际是只在DWG文档增加了块参照的插入点击比例因子等定义,并没有增加其他任何实体,只在块最初定义时根据块内图元增加了实体。
属性块的定义
属性块是有构成的实体和附加信息(属性)组成的,属性块中块的定义与简单块中块的定义一样,而属性的定义主要是通过属性的AttributeDefinition类的有关属性和函数来实现的。具体实现有:
a 、AttributeDefinition类的实例并设置对象的属性值;
b、由于块的属性定义也可以看做是块中的实体,可以通过块表记录类的成员函数AppendEntity将属性定义附加到块中。
其中,属性定义的属性值主要有:文字的插入点、高度、旋转角度、对齐方式和宽度;
属性的默认值;属性的模式,如不可见方式Invisible、常量方式Constant、验证方式Verify、预置方式Preset;属性标签名。
插入一个属性块时,同普通块一样,块内普通图元不存在新增,块定义的时候就新增好了。但是AttributeDefinition实体时新增的。就是每增加一个属性块,每个单独的块的属性都是作为单独的新增实体加入文档数据库内所以我们在CAD中画图时候,改变属性块的定义的时候,新增的属性块的文字不会发生任何改变。
二.代码
public static void InsertPropertyBlock(string blockPath,Dictionary<string,string> vals) { Document document = Application.DocumentManager.MdiActiveDocument; Database database = document.Database; Database dbBlock = GetDB(blockPath, FileShare.Read); using(Transaction trans = database.TransactionManager.StartTransaction()) { string blockName = Path.GetFileNameWithoutExtension(blockPath); ObjectId blockId= database.Insert(blockName, dbBlock, false); //这一行,源代码没有加 BlockTable blockTb = trans.GetObject(database.BlockTableId, OpenMode.ForWrite) as BlockTable; BlockTableRecord blockTbRec = trans.GetObject(database.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; //ObjectId blockId = blockTb[blockName]; BlockReference br = new BlockReference(new Point3d(100, 100, 0), blockId); blockTbRec.AppendEntity(br); //块表记录,这个块表只包含定义的属性块内的图形 BlockTableRecord record = blockId.GetObject(OpenMode.ForRead) as BlockTableRecord; //判断块表记录是否包含属性 if (record.HasAttributeDefinitions) { foreach(ObjectId id in record) { //检查是否为属性定义 AttributeDefinition definition = id.GetObject(OpenMode.ForRead) as AttributeDefinition; if (definition != null) { //创建一个新的属性对象 AttributeReference attr = new AttributeReference(); attr.SetAttributeFromBlock(definition, br.BlockTransform); attr.Rotation = br.Rotation; attr.Position = br.Position.TransformBy(br.BlockTransform); attr.AdjustAlignment(database); //判断是否包含了指定的属性名称 if (vals.ContainsKey(definition.Tag.ToUpper())) { //设置属性值 attr.TextString = vals[definition.Tag.ToUpper()].ToString(); } //向块参照添加属性对象 br.AttributeCollection.AppendAttribute(attr); trans.AddNewlyCreatedDBObject(attr, true); } } } trans.AddNewlyCreatedDBObject(br, true); trans.Commit(); } } public static Database GetDB(string sourceFileName, FileShare share) { Database db; try { db = new Database(false, true); db.ReadDwgFile(sourceFileName, share, true, null); db.CloseInput(true); } catch { db = null; } return db; }
应用代码
[CommandMethod("InsertAttributeBlock")] public static void InsertAttributeBlock() { string path = @"C:UsersAdministratorDesktopJACK.dwg"; Dictionary<string, string> dict = new Dictionary<string, string>(); dict.Add("JACK", "kkkkkkkkkkkk"); BlockOperationCommon.InsertPropertyBlock(path, dict); }
三.总结
插入属性块的步骤:
1.根据块文件路径信息读取块文件(.dwg文件)的数据库信息(Database)。
2.将读取到数据库插入当前DWG图形文件的数据库中----ObjectId blockId= database.Insert(blockName, dbBlock, false);
返回的是插入后的块定义id
3.实例化块参照(BlockReference),并将其添加到块表记录中
BlockReference br = new BlockReference(new Point3d(100, 100, 0), blockId);
blockTbRec.AppendEntity(br);
上述就将块的普通块定义部分以块参照的存在,插入当前文档。
4.读取块定义内的图形文件,确认是否包含属性定义信息
BlockTableRecord record = blockId.GetObject(OpenMode.ForRead) as BlockTableRecord;
//判断块表记录是否包含属性
if (record.HasAttributeDefinitions)
5.遍历当前块定义内的图形文件ID,实例化属性参照,对属性参照记性赋值
6.将块参照的属性集合添加此定义的属性,并进行事务添加
7.块参照的事务提交