首页天道酬勤AutoCAD二次开发实用教程,python做cad二次开发

AutoCAD二次开发实用教程,python做cad二次开发

张世龙 05-13 09:02 66次浏览

方法添加TypedValue可以添加多个TypedValue,但总数据大小不能超过128K。

resultbufferresbuf=newresultbuffer (; resbuf.add(newtypedvalue((int ) DxfCode.Text,'我的扩展数据') ) resbuf.add(newtypedvalue((int ) DxfCode.Real ) resbuf.add(newtypedvalue((int ) DXF code.int 32,5 );

扩展数据——XData

可以向AutoCAD数据库对象中灵活地添加一定量的自定义数据供开发人员使用。 这些数据的含义由开发人员自己解释。 无论其含义如何,AutoCAD都会维护这些数据。 这些数据称为XData,扩展数据作为结果缓存附加到实体,这对于充分利用存储空间和添加轻量级数据非常有用。

可以从实体DBObject类及其派生类的XData属性中获取或设置扩展数据。 的扩展数据由APP应用程序创建,附加到实体的扩展数据可以包含一个或多个组。 每个组都以不同的注册APP应用程序名称开始,扩展数据XData支持的TypedValue.TypeCode属性值(DXF组码)只能采用1000到1071之间的组码值。 不同的组码对应不同类型的信息。 各组码的说明如下表所示。

XF组码值扩展数据内容1000~1009字符串(最多255个字符

符号)

1001Xdata的APP应用程序名称1002Xdata的控制字符串1003图层名称1004二进制数据1005数据库对象句柄1012~1059浮点数1010、1020、1030三维点(x、y、z ) 1012, 1022 1033三维空间方向1040Xdata上浮点数1041Xdata上的距离值1042Xdata上的比例系数1060~107016位整数107132位整数

由于每个数据库对象都可以附加来自多个APP应用程序的数据,因此在ResultBuffer中,APP应用程序名称是每个扩展数据的第一个数据,然后生成的缓冲区数据归该APP应用程序名称所有。 (您可以使用其他特殊标识作为第一个数据,但无论如何都很容易区分,目的是便于以后查询此扩展数据。)

AutoCAD将注册的APP应用程序名称存储在数据库的RegAppTable表中。 在使用之前,必须首先检测RegAppTable表中是否已存在,如果不存在,则进行注册。 这意味着创建RegAppTableRecord表记录。 注册程序的名称最多可包含31个字符,并使用以下代码完成regapptableecord

regapptableapptbl=trans.getobject (db.regapptableid,OpenMode.ForWrite ) as RegAppTable; if (! appTBL.has(myappname ) ) regapptablerecordapptblrcd=newregapptablerecord ); appTblRcd.Name='MyAppName '; appTBL.add(apptblrcd; trans.addnewlycreateddbobject (apptblrcd,true ); }

要向数据库对象添加扩展数据,必须首先获取数据注册APP应用程序名称,然后根据DBObject类及其派生类的XData属性设置扩展数据。如以下代码所示

publicvoidaddxdata ({ editored=application.document manager.mdiactivedocument.editor; ed.WriteMessage (添加'扩展数据XDATA\n ' ); promptentityoptionsentops=newpromptentityoptions (“选择实体对象”); PromptEntityResult entRes; 输入=ed.get entity (en tops ); if(Entres.Status!=prompt status.ok (ed.write message )“对象选择失败。 结束”); 返回; } ObjectId objId=entRes.ObjectId; databasedb=hostapplicationservices.working database; 用户(tr )

ansaction trans = db.TransactionManager.StartTransaction())   {     Entity ent = trans.GetObject(objId, OpenMode.ForWrite) as Entity ;     ent.ColorIndex =1;     RegAppTable appTbl = trans.GetObject(db.RegAppTableId, OpenMode.ForWrite) as RegAppTable ;     if (!appTbl.Has("MyAppName"))     {       RegAppTableRecord appTblRcd = new       RegAppTableRecord();       appTblRcd.Name ="MyAppName";       appTbl.Add(appTblRcd);       trans.AddNewlyCreatedDBObject(appTblRcd, true);     }     ResultBuffer resBuf = new ResultBuffer();    resBuf.Add(new TypedValue(1001, "我的扩展数据应用程序"));    resBuf.Add(new TypedValue(1000, "作者:王"));    ent.XData = resBuf;     trans.Commit();   } }

  从指定的对象返回所附着的扩展数据也需要通过 DBObject 类及其派生类的XData 属性,返回的结果为 ResultBuffer,可以用.AsArray()方法将其转换为一个TypedValue[]数组,或者借助遍历器 IEnumerator(在 System.Collections 命名空间中),同时根据 DXF 的组码值判断所添加的数据,这些数据的含义由开发者自行解释。

  使用自带方法转为数组:

TypedValue[] tvs = rb.AsArray();

  使用IEnumerator遍历:

public void GETXDATA() {   Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;   ed.WriteMessage("获取扩充数据 XDATA\n");   PromptEntityOptions entOps = new PromptEntityOptions("选择实体对象");   PromptEntityResult entRes = ed.GetEntity(pr);   if (entRes.Status != PromptStatus.OK)   {     ed.WriteMessage("选择对象失败,退出");     return;   }   Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;   using (Transaction tr = db.TransactionManager.StartTransaction())   {     Entity ent = (Entity)tr.GetObject(res.ObjectId, OpenMode.ForRead);     ResultBuffer resBuf = ent.XData;     if (resBuf ! = null)     {       IEnumerator iter = resBuf.GetEnumerator();       while (iter.MoveNext())       {         TypedValue tmpVal = (TypedValue)iter.Current;         ed.WriteMessage(tmpVal.TypeCode.ToString() + ":");         ed.WriteMessage(tmpVal.Value.ToString() +"\n");       }     }   } }

  也可以将扩展数据读取到更常用的List<T>中,参考代码如下:

public List<System.Object> GetXDataList(Entity ent){  Editor ed = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Editor;  List<System.Object> objs = new List<System.Object>();  Database db = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument.Database;  using (Transaction trans = db.TransactionManager.StartTransaction())  {    ent = (Entity)trans.GetObject(ent.ObjectId, OpenMode.ForRead);    ResultBuffer resBuf = ent.XData;    if (resBuf != null)    {      System.Collections.IEnumerator itor = resBuf.GetEnumerator();      while (itor.MoveNext())      {        TypedValue tmpVal = (TypedValue)itor.Current;        objs.Add(tmpVal.Value); }    }    trans.Commit();  }  return objs;}

 

  要注意的是,XData是比较特殊的,给实体添加扩展数据,是这样的:

ResultBuffer rb = new ResultBuffer(  new TypedValue[]{   new TypedValue((int)DxfCode.ExtendedDataRegAppName,"abc"), new TypedValue((int)DxfCode.ExtendedDataAsciiString,"123") });line.XData = rb;

  但是这里虽然是用等号赋值的,但是它并不一定会覆盖旧的扩展数据,一个实体,只有一个XData属性,但是里面可以记录多个不同应用程序名的扩展数据。

  每次用“=”给实体的XData赋值时,如果XData里还没有这个应用程序的扩展数据,那么新赋的这些值,会被添加到原有的XData结尾去,比如上面已经给line对象添加了应用程序“abc”的扩展数据,这个时候读取line的XData,其内容应该是这样的:

new TypedValue[]{ new TypedValue((int)DxfCode.ExtendedDataRegAppName,"abc"), new TypedValue((int)DxfCode.ExtendedDataAsciiString,"123")}

  这时候,再给line添加一个新的应用程序"lc"的扩展数据:

ResultBuffer rb1 = new ResultBuffer(new TypedValue[]{  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"lc"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"0")});line.XData = rb1;

  此时,如果再读取line的XData,那么结果就会是:

new TypedValue[]{  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"abc"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"123"),  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"lc"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"0")}

  这样的话,那如果同一个实体如果有多个应用程序的扩展数据,那我怎么取其中某一个应用程序的扩展数据呢?

  答案是使用:GetXDataForApplication方法,该方法的参数就是应用程序名,比如:

ResultBuffer res = line.GetXDataForApplication("abc");这样取到的结果就是:new TypedValue[]{  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"abc"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"123")}

 

  如果要修改扩展数据,只需要对XData重新赋值就行,比如现在我们修改应用程序abc的扩展数据:

line.XData = new ResultBuffer(new TypedValue[]{  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"abc"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"1231"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"1")});//对XData重新赋值时,如果XData里已经有了abc的扩展数据,那么会把原有的abc的扩展数据替换掉,如果现在还没有abc的扩展数据,那么就会在XData结尾处添加上新的扩展数据。

 

  如果要删除扩展数据,操作方式如下:

//删除应用程序abc的扩展数据,只需要进行一个这样的赋值,新值里只添加一个应用程序名,不添加其他值,这样XData中,原有的abc的扩展数据就会被删除line.XData = new ResultBuffer(  new TypedValue[]{  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"abc")});

  注意:尽量不要直接删除已经在RegAppTable里注册的应用程序名,如果图纸上的实体上添加了此应用程序的扩展数据,那么扩展数据中对应的应用程序名会被删掉,但它下面对应的其他数据值并不会被删除,有可能会引发问题,例如:

//删除应用程序abc在RegAppTable里的记录RegAppTable rat = (RegAppTable)trans.GetObject(db.RegAppTableId, OpenMode.ForWrite);if (!rat.Has("abc")){  RegAppTableRecord ratr = (RegAppTableRecord)rat["abc"].GetObject(OpenMode.ForWrite);  ratr.Erase();}//这时,读取line的XData,其内容会是这样(假设我们上一步,没有删除line中abc的扩展数据)new TypedValue[]{  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"123"),  new TypedValue((int)DxfCode.ExtendedDataRegAppName,"lc"),  new TypedValue((int)DxfCode.ExtendedDataAsciiString,"0")}

  所以,个人认为,在删除RegAppTable中的已注册的应用程序名时,应先用过滤选择器选择出添加了此应用程序扩展数据的实体,然后将它们的扩展数据删除,然后再去删除RegAppTable中的应用程序注册信息。

单片机idata区是指,idata与xdata 监控系统方案设计,监控系统技术方案