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