1 Transaction介绍

一般而言数据库的增删改查操作统一交给Transaction(事务)处理,AutoCAD也不例外,它将所有对象以图形数据库的形式存储,并将对象的打开和关闭交给唯一的TransactionManager进行管理,因此TransactionManager必须是一个全局对象,且随AutoCAD启动而创建,并管理多个被AutoCAD打开的dwg文档。

存储在硬盘的dwg文档里面的每个对象都要有一个唯一的编号Handle,这样才被AutoCAD正确索引。而被Transaction Manager从硬盘取出放入内存的对象也会被重新分配一个唯一的编号ObjectId,它本质是一个内存地址,有了这个地址我们在代码里面就可以访问到这个对象。

TransactionManager简化了数据库的存储操作,使对象的增删改查主要涉及4个函数:StartTransaction、GetObject、AddNewlyCreatedDBObject、Commit。其中StartTransaction函数是获得Transaction对象的唯一入口,当添加新的对象到内存并得到一个与之关联的ObjectId后,还需要调用AddNewlyCreatedDBObject函数通知TransactionManager,使后续将要被调用的Commit函数将对象存入硬盘,并为该对象分配Handle。

一段简单的添加对象的代码如下:

/// <summary>
/// 添加表记录(BlockTable DimStyleTable LayerTable LinetypeTable RegAppTable TextStyleTable UCSTable ViewportTable ViewTable)
/// </summary>
/// <param name="symbolTableRecord"></param>
/// <param name="symbolTableId"></param>
/// <returns></returns>
private static ObjectId AddSymbolTableRecord(SymbolTableRecord symbolTableRecord, ObjectId symbolTableId)
{using (Transaction tr = GetActiveDatabase().TransactionManager.StartTransaction()){SymbolTable st = (SymbolTable)tr.GetObject(symbolTableId, OpenMode.ForRead);if (!st.Has(symbolTableRecord.Name)){st.UpgradeOpen();st.Add(symbolTableRecord);tr.AddNewlyCreatedDBObject(symbolTableRecord, true);tr.Commit();}return st[symbolTableRecord.Name];}
}

上面的代码对于大部分对象的添加都是可用的,但是对于关联对象不适用,比如AttributeReference(属性参照),因为每个AttributeReference必须关联一个BlockReference(块参照),在增加AttributeReference对象时,需首先打开关联的BlockReference对象,否则出错。对AttributeReference添加的代码如下:

/// <summary>
/// 为块参照添加属性
/// </summary>
/// <param name="objectId"></param>
/// <param name="list"></param>
public static void AppendAttribute(ObjectId objectId, params AttributeReference[] list)
{using (Transaction tr = GetActiveDatabase().TransactionManager.StartTransaction()){BlockReference br = tr.GetObject(objectId, OpenMode.ForWrite) as BlockReference;if (br == null) throw new Exception("AppendAttribute params error");foreach (var item in list){br.AttributeCollection.AppendAttribute(item);tr.AddNewlyCreatedDBObject(item, true);}tr.Commit();}
}

2 Transaction实例

下面展示的实例是建筑制图里经常要用到的标高符号的绘制,它由三角形、水平线和文字组成,文字的内容为高程或标高,一般等于Y坐标的值。当坐标系或者位置变化后,还需要对它们的文字内容进行更新。

3 主要代码

主要代码如下:

//创建标高
[CommandMethod("bat_bg")]
public void Sub17()
{double offset = 0;if (InputHelper.GetDouble(ref offset, "\n输入标高符的水平向偏移距离")){//得到属性块IDObjectId attributeBlockId = EntityHelper.GetBlockId("BAT_FFF_BG");//没有则创建属性块if (attributeBlockId == ObjectId.Null){AttributeDefinition attributeDefinition = new AttributeDefinition();attributeDefinition.Tag = "BG";attributeDefinition.Height = 2.5;attributeDefinition.WidthFactor = 0.75;attributeDefinition.HorizontalMode = TextHorizontalMode.TextLeft;attributeDefinition.VerticalMode = TextVerticalMode.TextBase;attributeDefinition.Position = new Point3d(2.2, 0.5, 0);attributeDefinition.SetDatabaseDefaults();attributeBlockId = EntityHelper.CreatEmptyBlock("BAT_FFF_BG");EntityHelper.AddEntity2Block(attributeDefinition, attributeBlockId);}//得到块属性AttributeDefinition attdef = EntityHelper.GetBlockAttribute(EntityHelper.GetBlockId("BAT_FFF_BG"), "BG");double dimscale = EntityHelper.GetActiveDatabase().Dimscale;var ucs = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;DrawJigFramework djf = new DrawJigFramework();do{//创建块参照BlockReference blockReference = new BlockReference(Point3d.Origin, attributeBlockId);//创建属性参照                AttributeReference attributeReference = new AttributeReference();attributeReference.SetAttributeFromBlock(attdef, blockReference.BlockTransform);attributeReference.TextString = attdef.TextString;attributeReference.Rotation = attdef.Rotation;attributeReference.Position = attdef.Position;attributeReference.AdjustAlignment(EntityHelper.GetActiveDatabase());//创建标高箭头Polyline polyline = new Polyline();polyline.AddVertexAt(0, Point2d.Origin, 0, 0, 0);polyline.AddVertexAt(0, Point2d.Origin + new Vector2d(-1, Math.Sqrt(3)), 0, 0, 0);polyline.AddVertexAt(0, Point2d.Origin + new Vector2d(1, Math.Sqrt(3)), 0, 0, 0);polyline.AddVertexAt(0, Point2d.Origin, 0, 0, 0);polyline.AddVertexAt(0, Point2d.Origin, 0, 0, 0);//Jigdjf.JigEntity = new List<Entity>() { polyline, blockReference, attributeReference };djf.JigEntity.ForEach(l => l.Move(offset, 0));djf.JigEntity.ForEach(l => l.Scaling(Point2d.Origin, dimscale));djf.JigPhases = new List<Phase>() { new PointPhase("\n输入标高所在点", false) };djf.JigUpdate = () =>{Point3d pt0 = (Point3d)djf.JigPhases[0].Value;//更新属性参照文字attributeReference.TextString = pt0.Y.S3();polyline.RemoveVertexAt(0);Point2d pt = new Point2d((offset + 2.2) * dimscale + attributeReference.GetGeometricWidth() * 1.1, 0);polyline.AddVertexAt(0, pt, 0, 0, 0);//坐标变换djf.JigMatrix = ucs * Matrix3d.Displacement(pt0.GetAsVector());//返回真表示需要重绘return true;};djf.JigEnding = () =>{djf.JigEntity.ForEach(l => l.TransformBy(djf.JigMatrix));EntityHelper.AppendAttribute(blockReference.Post2CurrentSpace(), attributeReference);EntityHelper.Post2CurrentSpace(polyline);//返回假表示不用添加实体return false;};} while (djf.Jig2CurrentSpace());}
}//更新标高
[CommandMethod("bat_gxbg")]
public void Sub18()
{ObjectId[] ids = new ObjectId[] { };if (InputHelper.GetEntityIds(ref ids, "\n选择需要更新的标高", TypeValueHelper.Insert)){var ucs = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;foreach (BlockReference item1 in ids.Select(l => EntityHelper.GetEntityById(l) as BlockReference).ToList()){foreach (ObjectId item2 in item1.AttributeCollection){AttributeReference attref = EntityHelper.GetEntityById(item2) as AttributeReference;if (attref.Tag == "BG"){EntityHelper.UpdateEntity<AttributeReference>(item2, l =>{l.TextString = item1.Position.TransformBy(ucs.Inverse()).Y.S3();});break;}}}}
}

AutoCAD.net Transaction实例4 标高相关推荐

  1. python处理cad_python3读取autocad图形文件.py实例

    废话不多说,看代码吧! ''' 待完善. 此代码实现了,根据标注文本的 属性,数值,位置,及 容差, 去判断 设计 和 实测两图中的同一位置的尺寸. 如果是同一位置的尺寸,则进行比较, 并把结果存成表 ...

  2. python读取cad_python3读取autocad图形文件.py实例

    废话不多说,看代码吧! ''' 待完善. 此代码实现了,根据标注文本的 属性,数值,位置,及 容差, 去判断 设计 和 实测两图中的同一位置的尺寸. 如果是同一位置的尺寸,则进行比较, 并把结果存成表 ...

  3. python dwg文件 读取_python3读取autocad图形文件.py实例

    废话不多说,看代码吧! ''' 待完善. 此代码实现了,根据标注文本的 属性,数值,位置,及 容差, 去判断 设计 和 实测两图中的同一位置的尺寸. 如果是同一位置的尺寸,则进行比较, 并把结果存成表 ...

  4. AutoCAD.net Jig实例1 动态标尺

    1 Jig介绍 讲Jig实例之前,先将Jig相关捋一捋..net托管类(Managed Class) 封装了大部分 ObjectARX C++类.在.net中,Jig功能被封装在了一个父类(Jig)和 ...

  5. python autocad显示_通过Python打开Autocad的新实例

    有人有在Autocad中使用Python的经验吗?我只是在尝试,作为一个测试,看看我是否可以通过Python打开一个新的Autocad实例,尽管PyAutocad工作得很好(如果您有其他建议,请随时提 ...

  6. AutoCAD .Net 入门实例

    以下以 VS2010 开发 AutoCAD2014 的实例来讲解. 一.新建项目 新建 C# 类库项目,.Net Framework选择4.0版本. 二.添加引用 添加引用: * accoremgd ...

  7. AutoCAD.net AttributeBlock实例3 炸属性块

    1 AttributeBlock介绍 AttributeBlock这个名称并不存在于.net开发文档中,是我根据中文名称"属性块"直译的,可能不对,只是叫起来顺口.开发文档中与属性 ...

  8. AutoCAD.net CurveMeasurement实例2 径向线

    1 Curve Measurement Functions介绍 在AutoLisp开发里面,有一组以vlax-curve-get开头的曲线测量函数比较好用,主要功能是提供曲线上某一点的坐标.距离.切线 ...

  9. hibernate的Transaction接口理解

    Transaction接口是对事物实现的一个抽象,这些实现包括JDBC事务等.Hibernate框架中的事物通过hibernate.cfg.xml文件选择JDBC.在transaction接口中定义了 ...

  10. 解决Win系统cad激活安装失败问题,AutoCad 2022 中文/英文正式详细安装教程

    Autodesk AutoCAD 2022简称"cad 2022"是一款功能强大的CAD三维绘图辅助设计软件.autocad 2022适用于二维绘图.详细绘制.设计文档和基本三维设 ...

最新文章

  1. 更大的工字型电感作为150kHz导航信号接收天线
  2. Java并行程序基础(十二)
  3. 戴尔服务器r210显示3,Dell服务器R210
  4. hdu4396 多状态spfa
  5. 如何保护企业网络免受DDoS攻击?—Vecloud微云
  6. 原生JS forEach()和map()遍历的区别以及兼容写法
  7. 机器视觉 · 工业镜头
  8. Linux下mysql设置密码
  9. Ubuntu下安装Wine可能导致假死问题解决方案
  10. scala字符串替换_如何在Scala中替换字符串中的正则表达式模式?
  11. c语言中因式分解的题目,因式分解相关练习题
  12. 不能忽视的情绪 -- 喜怒哀惧,也不过度关注
  13. 教大家一个免费复制粘贴百度文库文字的方法
  14. EasyAR WebAR开发
  15. 自动生成员工号c语言,C语言课程设计级.doc
  16. 无法打开internet站点,ie无法打开站点的解决方法【图解】
  17. js将 一串数字1403149534转换为日期格式
  18. word排版案例报告_导师:论文排版都搞不好,你拿什么去投稿?!
  19. 英语阅读重点单词总结
  20. 应用性能管理-从操作系统做起

热门文章

  1. pp助手苹果版本_曾经iOS一代越狱神奇器,PP助手宣布凉凉
  2. Springboot——quartz简单配置和使用
  3. 如何根据项目进行PLC选型
  4. 【登陆设计】-【技术上】你会做WEB上的用户登录功能吗?
  5. Ajax请求破解百度云限速下载教程方法(图片教程)
  6. c++ ——第一个MFC界面
  7. vwmare 15“无权输入许可证密钥...”与出现新问题hadoop集群无法启动
  8. Spire PDF转WORD (高效不失真)
  9. VM14无法将网络更改为桥接状态:没有未桥接的主机网络适配器
  10. 如何防止数据库中的信息被“脱库”-笔记