本案例功能为选择当前文档中一个块(旧块),然后选择新图元(新块),运行插件后新块将替换图中所有的旧块。
效果如下:
public static class Class1{//选取对象替换块定义[CommandMethod("TT")]public static void BLKREDEF(){Document doc =Z.doc;Database db = doc.Database;Editor ed = doc.Editor;ed.WriteMessage("图块编辑替换 BK");//提示选择块PromptEntityOptions peo = new PromptEntityOptions("\n请选择需要编辑的块");peo.SetRejectMessage("\n你选择的不是块");peo.AddAllowedClass(typeof(BlockReference), true); //只让选择块PromptEntityResult per = ed.GetEntity(peo);if (per.Status != PromptStatus.OK) { return; }ObjectId blockID = per.ObjectId;string blockName;Point3d blockInPt;double blockAngle;Matrix3d blockMatri, blockInMatri;using (Transaction trans = doc.TransactionManager.StartTransaction()){BlockReference blockref = (BlockReference)trans.GetObject(blockID, OpenMode.ForRead); //块参照blockName = blockref.Name; //块名blockInPt = blockref.Position; //块插入点blockAngle = blockref.Rotation; //块旋转blockMatri = blockref.BlockTransform;blockInMatri = blockMatri.Inverse(); //逆矩阵}ed.WriteMessage("\n您编辑的块名为: " + blockName);//提示选择对象PromptSelectionOptions pso = new PromptSelectionOptions();pso.MessageForAdding = "请选择需要生成块的图形";pso.RejectObjectsOnLockedLayers = true; //不能选在锁定图层上的PromptSelectionResult psr = ed.GetSelection(pso);if (psr.Status != PromptStatus.OK) { return; }SelectionSet ss = psr.Value;//新对象的基点//注意交互下的坐标都是UCS,需要处理PromptPointOptions ppo = new PromptPointOptions("请选择新块基点:");ppo.UseBasePoint = true;ppo.BasePoint = blockInPt.TransformBy(ed.CurrentUserCoordinateSystem.Inverse());PromptPointResult ppr = ed.GetPoint(ppo);if (ppr.Status != PromptStatus.OK) { return; }Point3d blockInPtN = ppr.Value;Point3d inPtNWCS = blockInPtN.TransformBy(ed.CurrentUserCoordinateSystem);//坐标系变换,从UCS转换到WCSVector3d vt = blockInPt - inPtNWCS;Matrix3d matMove = Matrix3d.Displacement(vt); //平移using (Transaction trans = doc.TransactionManager.StartTransaction()){//获取块参照的定义BlockReference blockRef = (BlockReference)trans.GetObject(blockID, OpenMode.ForWrite);BlockTableRecord btr = (BlockTableRecord)blockRef.BlockTableRecord.GetObject(OpenMode.ForWrite);//遍历删除原块内所有对象foreach (ObjectId id in btr){Entity ent = (Entity)trans.GetObject(id, OpenMode.ForWrite);ent.Erase();}//实体列表加入新建的块表记录中foreach (ObjectId id in ss.GetObjectIds()){Entity ent = (Entity)trans.GetObject(id, OpenMode.ForWrite);//要排除自身嵌套Bugif (ent is BlockReference){if (((BlockReference)ent).Name == blockName){continue;}}IdMapping mapping = new IdMapping();Entity ent1 = (Entity)ent.Clone(); //复制新的并加入块// Entity ent1 = (Entity)ent.DeepClone(ent, mapping, false);//块定义以时候会以(0,0,0)为基点//插入的时候坐标会以飞一个相对(0,0,0)到inPt的距离,这里要处理一下。//预先把对象移到原点ent1.TransformBy(blockInMatri * (matMove));btr.AppendEntity(ent1);trans.AddNewlyCreatedDBObject(ent1, true);//ent.Erase(); //删除原来的}//通知事务处理//trans.AddNewlyCreatedDBObject(bt, true);//刷新块显示//blockRef.RecordGraphicsModified(true);//模型空间打开块表BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);//打开指定块名的块表记录BlockTableRecord btr1 = (BlockTableRecord)trans.GetObject(bt[blockName], OpenMode.ForRead);//获取指定块名的块参照集合的IdObjectIdCollection blockIds = btr1.GetBlockReferenceIds(false, true);foreach (ObjectId id in blockIds) // 遍历块参照的Id{//获取块参照BlockReference block = (BlockReference)trans.GetObject(id, OpenMode.ForWrite);block.Visible = block.Visible;}trans.Commit();}}}
修改快标注:
// 获取块参照对应的块定义(BlockTableRecord)
var blockDef = (BlockTableRecord)trans.GetObject(blockRef.BlockTableRecord, OpenMode.ForRead);
foreach (ObjectId blockDefObjId in blockDef)
{
Entity blockDefEntity = trans.GetObject(blockDefObjId, OpenMode.ForWrite) as Entity;
if (blockDefEntity is Dimension)
{
Dimension dim = blockDefEntity as Dimension;
// 属性值替换、并计算四则运算结果
if (!String.IsNullOrEmpty(dim.DimensionText))
{
dim.DimensionText = "125";
}
}
}