欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

AutoCAD.net Transaction实例4 标高

发布时间:2023/12/9 55 豆豆
生活随笔 收集整理的这篇文章主要介绍了 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 标高的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。