C#+ObjectArx CAD二次開發(2)


 前面開了一個頭,這里添加幾個功能的實現,

   //添加圖層
        private void LoadLayer()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            using (Transaction tr = acDoc.TransactionManager.StartTransaction())
            {
                //指定點圖層
                LayerTable lt = (LayerTable)tr.GetObject(acDoc.Database.LayerTableId, OpenMode.ForRead);
                if (!lt.Has("test"))//判斷是否存在
                {//不存在添加
                    var LayerID = ObjectId.Null;
                    LayerTableRecord ltr = new LayerTableRecord();
                    ltr.Name = "test";
                    ltr.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(
                        Autodesk.AutoCAD.Colors.ColorMethod.ByColor, 130);
                    lt.UpgradeOpen();
                    LayerID = lt.Add(ltr);
                    tr.AddNewlyCreatedDBObject(ltr, true);
                }
                tr.Commit();
            }
        }

        private bool isBCAD = false;
        /// <summary>
        /// 列出所有對象
        /// </summary>
        [CommandMethod("LE",CommandFlags.Transparent)]
        public  void ListEntities()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor acadEd = Application.DocumentManager.MdiActiveDocument.Editor;
            Database acCurDb = acDoc.Database;
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                BlockTable acBlkTbl;
                acBlkTbl = acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead) as BlockTable;
                BlockTableRecord acBlkTblRec;
                acBlkTblRec = acTrans.GetObject(acBlkTbl[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
                int nCnt = 0;
                acDoc.Editor.WriteMessage("\nModel space objects: ");
                foreach (ObjectId acObjId in acBlkTblRec)
                {

                    acDoc.Editor.WriteMessage("\n" + acObjId.ObjectClass.DxfName + ":" + acObjId.Handle.Value.ToString());
                    nCnt = nCnt + 1;
                }
                if (nCnt == 0)
                {
                    acDoc.Editor.WriteMessage("\nNo objects found.");
                }
                else
                {
                    acDoc.Editor.WriteMessage("\nTotal {0} objects.", nCnt);
                }
            }
        }

        private int _id = 0;
        /// <summary>
        /// 生成閉合區域,
        /// </summary>
        [CommandMethod("SetArea", CommandFlags.Transparent)]
        public void SetArea()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor acadEd = Application.DocumentManager.MdiActiveDocument.Editor;

            PromptPointOptions ptOpt = new PromptPointOptions("選擇點:\n");
            PromptPointResult ptRel = null;
            ObjectId[] ids = null;

            ptRel = acadEd.GetPoint(ptOpt);
            Database acCurDb = acDoc.Database;
            //該方法必須是ObjectArx2011以后的版本才支持,以前的版本可以用-bo命令加SelectImplied方法得到的選擇集來實現該功能
            var bound = acadEd.TraceBoundary(ptRel.Value, true);
   
            using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
            {
                foreach (var dbObj in bound)
                {
                    var line = dbObj as Polyline;
                    if (acCurDb != null) line.Color = Color.FromColor(System.Drawing.Color.Red);
                    BlockTable bt = (BlockTable)acTrans.GetObject(acCurDb.BlockTableId, OpenMode.ForRead);
                    BlockTableRecord btr = (BlockTableRecord)acTrans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                    var id = btr.AppendEntity(line);//添加實體
                    acTrans.AddNewlyCreatedDBObject(line, true);//保存到cad數據庫
                    //下面為實體添加擴展屬性,這里擴展屬性添加到實體的擴展字典中,也可以直接添加到實體的XData的屬性中
                    line.CreateExtensionDictionary();//為實體創建擴展字典
                    var dic = acTrans.GetObject(line.ExtensionDictionary, OpenMode.ForWrite) as DBDictionary;//獲取實體的擴展字典,DBDictionary,可以用通過SetAt和GetAt設置和獲取
                    var xrecord=new Xrecord();//創建Xrecord對象。里邊保存具體的擴展屬性對象
                    xrecord.Data = new ResultBuffer(new TypedValue((int) DxfCode.Text, "測試1"));//添加屬性對象都保存為ResultBuffer對象對應不同的DxfCode碼
                    dic.SetAt("exta", xrecord);//添加到字典中,繼承自DBObject的對象都可以作為value添加到字典中
                    acTrans.AddNewlyCreatedDBObject(xrecord, true);//因為添加的擴展屬性也是DBObject對象,要添加到cad的數據庫中
                    //這里添加一個cad的DataTable對象到字典
                    var dt = new DataTable();
                    dt.TableName = "polyattri";
                    dt.AppendColumn(CellType.Integer, "line_id");
                    var lineid = new DataCell();
                    lineid.SetInteger(_id);
                    var row = new DataCellCollection();
                    row.Add(lineid);
                    dt.AppendRow(row, true);
                    dic.UpgradeOpen();
                    dic.SetAt("attr", dt);
                    acTrans.AddNewlyCreatedDBObject(dt, true);
                    _id++;
                    acadEd.WriteMessage(line.ObjectId.ToString());
                }
                acTrans.Commit();
            }

        }
        //導入線型,根據線型文件和線名來加載線型,后面可以通過設置當前的環境變量來改變當前線型
        //路徑如果為文件名,cad會自動在主程序的相對路徑下搜索,如果是自定線型需要指定絕對路徑,
        //如果線型文件關聯SHX文件,記得要一起不然會加載失敗
        private void loadlinetype()
        {
            var lineTypeFile = "acadiso.lin";
            string lineTypeName = "acad_iso03w100";
            ObjectId idRet = ObjectId.Null;
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor acadEd = Application.DocumentManager.MdiActiveDocument.Editor;
            Database db = acDoc.Database;
            using (Transaction trans = db.TransactionManager.StartTransaction())
            {

                LinetypeTable ltt = (LinetypeTable)trans.GetObject(db.LinetypeTableId, OpenMode.ForWrite);
                LinetypeTableRecord lttr = new LinetypeTableRecord();

                if (ltt.Has(lineTypeName))
                {
                    idRet = ltt[lineTypeName];
                }
                else
                {
                    try
                    {
                        db.LoadLineTypeFile(lineTypeName, lineTypeFile);//加載線型
                        idRet = ltt[lineTypeName];
                    }
                    catch (System.Exception ex)
                    {
                        acadEd.WriteMessage(ex.Message);
                    }
                    finally
                    {
                        trans.Commit();
                    }
                }
            }
        }
        //設置線型
        [CommandMethod("SLT")]
        public void SetLineType()
        {
            string test = Application.GetSystemVariable("CELTYPE").ToString();
            Application.SetSystemVariable("CELTYPE", "acad_iso03w100");//通過改變環境變量來設置線型,CELTYPE對應當前線型
        }
        //刪除選中//這里實現先選中后刪除的操作
         [CommandMethod("DelS")]
        public void DelSelect()
        {
            Document acDoc = Application.DocumentManager.MdiActiveDocument;
            Editor acadEd = Application.DocumentManager.MdiActiveDocument.Editor;

            SelectionSet acSSet;
            var selectionRes = acadEd.SelectImplied();//對應選中的選擇集
            Database acCurDb = acDoc.Database;
            if (selectionRes.Status == PromptStatus.OK)
            {
                acSSet = selectionRes.Value;

                using (Transaction acTrans = acCurDb.TransactionManager.StartTransaction())
                {
                    foreach (var v in acSSet.GetObjectIds())
                    {
                        DBObject dbObj = acTrans.GetObject(v, OpenMode.ForWrite);
                        dbObj.Erase(true);
                    }
                    acTrans.Commit();
                }

            }
            else
            {
                acDoc.Editor.WriteMessage(selectionRes.Status.ToString());
            }
        }
               
        //選中線病獲取上面設置的擴展屬性,上面怎么添加的這邊就怎么解析Xrecord對象
        [CommandMethod("SLL")]
        public void SelectLine()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Polyline line;
            if(!SelectEntity(out line,"多段線"))return;
            if (line != null)
            {
                using (var tr = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
                {
                    var dic = tr.GetObject(line.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
                    ObjectId id = dic.GetAt("attr");
                    var dt = tr.GetObject(id, OpenMode.ForRead) as DataTable;
                    int index = dt.GetColumnIndexAtName("line_id");
                    var att = dt.GetCellAt(0, index).Value;
                    ed.WriteMessage(att + "\n");

                    id = dic.GetAt("exta");
                    var xrec = tr.GetObject(id, OpenMode.ForRead) as Xrecord;
                    foreach (var xdata in xrec.Data)
                    {
                        ed.WriteMessage(xdata.Value.ToString() + "\n");
                    }



                }

                // ed.WriteMessage("\n{0},{1}", line.StartPoint.X, line.StartPoint.Y);
                //ed.WriteMessage("\n{0},{1}", line.EndPoint.X, line.EndPoint.Y);
            }
  
        }
        //添加文字
        [CommandMethod("SLP")]
        public void SelectPoint()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var sel = ed.GetPoint("選擇點");
            var db = Application.DocumentManager.MdiActiveDocument.Database;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                BlockTable bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
                BlockTableRecord btr = (BlockTableRecord)tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);
                DBText txt = new DBText();
                txt.Position = sel.Value;
                txt.Height = 0.5;
                txt.TextString = "測試";
                
                btr.AppendEntity(txt);
                tr.AddNewlyCreatedDBObject(txt, true);
                tr.Commit();
            }
        }

        //選中所有的多段線
        [CommandMethod("SLPS")]
        public void SelectPolyline()
        {
            var ed = Application.DocumentManager.MdiActiveDocument.Editor;
            //添加過濾條件,可以添加類型/圖層條件不同的dxfcode對應不同的對象
            var tvs = new TypedValue[] { new TypedValue((int)DxfCode.Start, "LWPOLYLINE") };//LWPOLYLINE 對應Polyline對象,這里的類型字段可以用前面的列舉對象來查看···,
            var sf = new SelectionFilter(tvs);
            var sel = ed.SelectAll(sf);
            if (sel.Value == null) return;
            using (var tr=Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction())
            {
                var ids = sel.Value.GetObjectIds();
                foreach (var obj in ids)
                {
                    var line = tr.GetObject(obj, OpenMode.ForRead) as Polyline;
                    ed.WriteMessage(line.ObjectId.ToString());
                }
                tr.Commit();
            }
            
        }

        //跳轉到某點,用當前視圖的大小來設置view的大小,也可以直接指定大小
        [CommandMethod("FLYTOP")]
        public void FlytoPoint()
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var db = Application.DocumentManager.MdiActiveDocument.Database;
            var sel = ed.SelectPrevious();//ed.SelectLast();
            using (Transaction acTrans = db.TransactionManager.StartTransaction())
            {
                if(sel.Value==null)return;
                if(sel.Value.GetObjectIds().Length<1)return;
                var ent=acTrans.GetObject(sel.Value.GetObjectIds()[0], OpenMode.ForRead) as Entity;
                if (ent != null)
                {
                    ViewTableRecord view = new ViewTableRecord();
                    Extents3d ext = ent.GeometricExtents;
                    ext.TransformBy(ed.CurrentUserCoordinateSystem.Inverse());

                    Vector3d vec1 = new Vector3d(new double[] { 10, 10, 10 });
                    ext.MaxPoint.Add(vec1);
                    ext.MinPoint.Subtract(vec1);
                    view.CenterPoint = new Point2d((ext.MaxPoint.X + ext.MinPoint.X) / 2,
                        (ext.MaxPoint.Y + ext.MinPoint.Y) / 2);
                    view.Height = ed.GetCurrentView().Height;
                    view.Width = ed.GetCurrentView().Height;
                    ed.SetCurrentView(view);
                    Application.DocumentManager.MdiActiveDocument.TransactionManager.FlushGraphics();
                }
                acTrans.Commit();
            }

        }
        //選擇一個實體對象,取消或者選中返回
        private bool SelectEntity<T>(out T obj, string entityName) where T : Entity
        {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var db = Application.DocumentManager.MdiActiveDocument.Database;
            PromptEntityOptions peo = new PromptEntityOptions(string.Format("\n請選擇{0}:", entityName));
            peo.SetRejectMessage(string.Format("\n必須是{0}!", entityName));
            peo.AddAllowedClass(typeof(T), false);
            obj = null;
            while (true)
            {
                var selection = ed.GetEntity(peo);
                if (selection.Status == PromptStatus.OK)
                {
                    using (var tr = db.TransactionManager.StartTransaction())
                    {
                        obj = tr.GetObject(selection.ObjectId, OpenMode.ForRead) as T;
                        tr.Commit();
                        return true;
                    }
                }
                if (selection.Status == PromptStatus.Cancel)
                {
                    return false;
                }
            }
        }

        //隱藏圖層
        [CommandMethod("CTL")]
        public void LayerEnable()
        {
            var doc = Application.DocumentManager.MdiActiveDocument;
            Database db = doc.Database;
            using (Transaction trs = db.TransactionManager.StartTransaction())
            {
                  LayerTable lt = trs.GetObject(db.LayerTableId, OpenMode.ForRead) as LayerTable;
                var layer = trs.GetObject(lt["test"],  OpenMode.ForWrite) as LayerTableRecord;
                layer.IsOff = layer.IsOff ? false : true;

                trs.Commit();
            }
        }
    
 //獲取上一次選中或者創建的對象        
public Entity[] GetLast()
        {
            List<Entity> list = new List<Entity>();
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            var db = Application.DocumentManager.MdiActiveDocument.Database;
            var sel = ed.SelectPrevious();//上一次選中的
            if (sel.Value == null) sel = ed.SelectLast();//如果為空就設置為上一次創建的對象
            using (Transaction acTrans = db.TransactionManager.StartTransaction())
            {
                if (sel.Value == null) return null;
                ObjectId[] ids = sel.Value.GetObjectIds();
                foreach (var id in ids)
                {
                    list.Add(acTrans.GetObject(id, OpenMode.ForRead) as Entity);
                }
                acTrans.Commit();
            }
            return list.ToArray();
        }
 
         

 

  

 

 

另:

1 cad2012 調試的時候form中的斷點進不去,需要把NEXTFIBERWORLD變量改為0;這么改以后用com啟動cad加載dll時有時候會報錯, 調試和使用的時候注意設置這個

2  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM