AutoCAD.net Transaction实例4 标高
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 标高的全部内容,希望文章能够帮你解决所遇到的问题。
- 上一篇: NUMPY数据集练习 ---------
- 下一篇: Aswing入门教程 1.6 颜色和填充