今天这一篇继续上一周的话题,简单介绍一下CAD中的动态块。
我们在设计图纸中有一部分的图块就是动态块,除了普通图块调整插入位置以及缩放比例来确定位置以及大小的功能之外,动态块预先设置了部分“夹点”,可以更改图形的特性,决定一个块是否是动态块的属性是BlockReference类的布尔属性IsDynamicBlock,如下图所示,在CAD2014中,该属性是一个只读属性,也就是比较遗憾的是,我们不可以通过.NET的二次开发来插入动态块,但是可以来控制图形中已有的动态块。
在CAD的安装目录中,Sample文件夹下有一个Blocks and Tables - Metric.dwg文件以供我们参考,图形中有一个名叫Door的块,就是动态块,其效果如下面视频所示:
可以看到,两个箭头可以将门朝着水平方向和竖直方向镜像反转,从而是门有着四个朝向,这样比起使用角度控制方向更加智能且有着约束性。
下面我们就以这个门为例,封装一些与动态块相关的方法:
首先是获取动态块属性值的方法,由于IsDynamicBlock是只读属性,所以这个方法要在图形已经插入动态块之后执行,动态块所有的属性名字比较长:叫做DynamicBlockReferencePropertyCollection,存放在BlockReference类中,方法的代码如下:
public static string GetDynBlockValue(this ObjectId blockId, string propName){ string propValue = null;//用于返回动态属性值的变量 var props = blockId.GetDynProperties();//获得动态块的所有动态属性 //遍历动态属性 foreach (DynamicBlockReferenceProperty prop in props) { //如果动态属性的名称与输入的名称相同 if (prop.PropertyName == propName) { //获取动态属性值并结束遍历 propValue = prop.Value.ToString(); break; } } return propValue;//返回动态属性值}
public static DynamicBlockReferencePropertyCollection GetDynProperties(this ObjectId blockId){ //获取块参照 BlockReference br = blockId.GetObject(OpenMode.ForRead) as BlockReference; //如果不是动态块,则返回 if (br == null && !br.IsDynamicBlock) return null; //返回动态块的动态属性 return br.DynamicBlockReferencePropertyCollection;}
接下来是设置动态块中属性的方法,以及代表数据类型取值的枚举类型:
public static void SetDynBlockValue(this ObjectId blockId, string propName, object value){ var props = blockId.GetDynProperties();//获得动态块的所有动态属性 //遍历动态属性 foreach (DynamicBlockReferenceProperty prop in props) { //如果动态属性的名称与输入的名称相同且为可读 if (prop.ReadOnly == false && prop.PropertyName == propName) { //判断动态属性的类型并通过类型转化设置正确的动态属性值 switch (prop.PropertyTypeCode) { case (short)DynBlockPropTypeCode.Short://短整型 prop.Value = Convert.ToInt16(value); break; case (short)DynBlockPropTypeCode.Long://长整型 prop.Value = Convert.ToInt64(value); break; case (short)DynBlockPropTypeCode.Real://实型 prop.Value = Convert.ToDouble(value); break; default://其它 prop.Value = value; break; } break; } }}
// 动态块的动态属性类型 public enum DynBlockPropTypeCode { String = 1, Real = 40, Short = 70, Long = 90 }
那么,接下来,我们注册一个命令,来插入动态块,这里前提还是图形中已经拥有这个块定义:
[CommandMethod("InsertDynBlock")]public void InsertDynBlock(){ Database db=HostApplicationServices.WorkingDatabase; using (Transaction trans=db.TransactionManager.StartTransaction()) { ObjectId model=db.GetModelSpaceId();//获取模型空间的ObjectId //表示块静态属性的字典对象 Dictionary<string,string> atts=new Dictionary<string, string>(); //添加门的各种静态属性 atts.Add("SYM.", "2"); atts.Add("WIDTH", "0.8m"); atts.Add("HEIGHT", "2m"); atts.Add("STYLE", "ONE PANEL"); atts.Add("REF#", "TS 1040"); atts.Add("MANUFACTURE", "TUR STYLE"); atts.Add("COST", "200.00"); //在模型空间的Doors层上插入表示门的Door块,插入点为原点,不旋转,不缩放 ObjectId blockId=model.InsertBlockReference("Doors", "Door", Point3d.Origin, new Scale3d(), 0, atts); //设置门的动态属性,宽度为0.8个单位,垂直方向翻转 blockId.SetDynBlockValue("Door Width", 0.8); blockId.SetDynBlockValue("Flip vertical", 1); trans.Commit(); }}
今天的内容就先介绍到这里,在之后的内容中,作为与今天内容相补充的内容,会介绍如何导入其他dwg文件中的块定义,这样更接近于平时工作的内容,敬请关注,如果有建议或是批评指教,欢迎在公众号内留言,谢谢!