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 颜色和填充