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("
Model space objects: ");
                foreach (ObjectId acObjId in acBlkTblRec)
                {

                    acDoc.Editor.WriteMessage("
" + acObjId.ObjectClass.DxfName + ":" + acObjId.Handle.Value.ToString());
                    nCnt = nCnt + 1;
                }
                if (nCnt == 0)
                {
                    acDoc.Editor.WriteMessage("
No objects found.");
                }
                else
                {
                    acDoc.Editor.WriteMessage("
Total {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("选择点:
");
            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 + "
");

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



                }

                // ed.WriteMessage("
{0},{1}", line.StartPoint.X, line.StartPoint.Y);
                //ed.WriteMessage("
{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("
请选择{0}:", entityName));
            peo.SetRejectMessage(string.Format("
必须是{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  

原文地址:https://www.cnblogs.com/onegarden/p/5694433.html