一.概念
塊定義與塊參照兩個概念
塊定義類似於模具,而塊參照類似於模具澆築出來的模型,在圖形中只需用塊定義來保存塊的實際幾何組成,而僅用插入點和比例因子來存儲塊定義,因為塊參照的幾何形狀與快參照完全一樣,僅大小不同,
好處
不需要存儲塊參照中的實體,減小了圖形文件;只需要修改塊定義,塊參照會自動更新,減輕了修改和維護工作。
插入一個普通塊實際是只在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:\Users\Administrator\Desktop\JACK.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.塊參照的事務提交
