using System; using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.Civil.ApplicationServices; using Autodesk.Civil.DatabaseServices; using Surface= Autodesk.Civil.DatabaseServices.Surface; using Autodesk.Civil.Settings; using System.IO; namespace ProfileTools { struct ser { public double station; public double elevation; public double radius; } //用於存儲樁號、高程及圓弧半徑的strcut /// <summary> /// 從文件創建縱斷面,模仿civil3d內部命令 /// 不同之處在於此命令創建的豎曲線為圓弧 /// 2018年2月12日,文件格式如下 /// 0,100 /// 100,105,200 /// 200,100,300 /// 300,108 /// 450,103 /// 550,104,400 /// 650,100 /// </summary> class CreateProfileFromFile { Document doc; Editor ed; CivilDocument civilDoc; ObjectId layerId; ObjectId styleId; ObjectId labelSetId; ObjectId alignmentId; string fileName; public CreateProfileFromFile() { doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument; ed = doc.Editor; civilDoc = Autodesk.Civil.ApplicationServices.CivilApplication.ActiveDocument; layerId = civilDoc.Settings.DrawingSettings.ObjectLayerSettings.GetObjectLayerSetting(SettingsObjectLayerType.Profile).LayerId; styleId = civilDoc.Settings.GetSettings<SettingsProfile>().StyleSettings.ProfileStyleId.Value; labelSetId = civilDoc.Settings.GetSettings<SettingsProfile>().StyleSettings.ProfileLabelSetId.Value; alignmentId = ObjectId.Null; fileName = null; } public void DoSth() { alignmentId = SelectAlignment(); //此方法為《AutoCAD Civil 3D .NET二次開發》8.1節中的方法,當然您也可以自己寫方法,只要獲取路線的Id即可。 if (alignmentId == ObjectId.Null) return; GetFileName(); if (fileName == null) return; List<ser> sers = new List<ser>(); using (StreamReader sr = new StreamReader(fileName)) { while (sr.Peek() >= 0) { string[] strs = sr.ReadLine().Split(','); double s = 0, e = 0, r = 0; if (strs.Length == 2) { double.TryParse(strs[0], out s); double.TryParse(strs[1], out e); } else if (strs.Length == 3) { double.TryParse(strs[0], out s); double.TryParse(strs[1], out e); double.TryParse(strs[2], out r); } ser oser = new ser(); oser.station = s; oser.elevation = e; oser.radius = r; sers.Add(oser); } } //2018年1月12日 //基本功能已實現,但很不完善, //需要判斷文件中樁號與路線長度的關系 //需要考慮半徑過大,無法實現的情況等 //創建縱斷面 ObjectId profilrid = Profile.CreateByLayout("test", alignmentId, layerId, styleId, labelSetId); //添加切線 using (Transaction tr = doc.Database.TransactionManager.StartTransaction()) { Profile pf = profilrid.GetObject(OpenMode.ForWrite) as Profile; ProfileEntityCollection pec = pf.Entities; for (int i = 0; i < sers.Count - 1; i++) { Point2d pt0 = new Point2d(sers[i].station, sers[i].elevation); Point2d pt1 = new Point2d(sers[i + 1].station, sers[i + 1].elevation); pec.AddFixedTangent(pt0, pt1); } tr.Commit(); } //重新開啟事務,添加圓弧 using (Transaction tr = doc.Database.TransactionManager.StartTransaction()) { Profile pf = profilrid.GetObject(OpenMode.ForWrite) as Profile; ProfilePVICollection pvis = pf.PVIs; ProfileEntityCollection pec = pf.Entities; for (int i = 1; i < sers.Count - 1; i++) { if (sers[i].radius != 0) { pec.AddFreeCircularCurveByPVIAndRadius(pvis[i], sers[i].radius); } } tr.Commit(); } } //---------------------------------------------------------------------- /// <summary> /// 獲取文件名稱 /// </summary> private void GetFileName() //獲取文件名 { Microsoft.Win32.OpenFileDialog openFileName = new Microsoft.Win32.OpenFileDialog(); //保存文件對話框 openFileName.Filter = "csv文件|*.csv|所有文件|*.*"; //后綴過濾器 openFileName.AddExtension = true; openFileName.Title = "保存文件"; //對話框標題 if (openFileName.ShowDialog() == true) //顯示對話框 { fileName = openFileName.FileName; //存儲文件名 } } //---------------------------------------------------------------------- ObjectId SelectEntity(string typeName, ObjectIdCollection ids, Type t) { PromptEntityOptions opt = new PromptEntityOptions( "\n選擇" + typeName + "<或按回車鍵從列表中選擇>"); opt.AllowNone = true; opt.SetRejectMessage("\n選定的圖元必須屬於類型:" + typeName); opt.AddAllowedClass(t, false); PromptEntityResult res = doc.Editor.GetEntity(opt); if (res.Status == PromptStatus.OK) //選擇對象 { return res.ObjectId; } else if (res.Status == PromptStatus.None) //如果沒選中對象, { //從對話框列表中選擇 using (FormSelectEntity fse = new FormSelectEntity(typeName, ids)) { fse.EntType = t; //設置選擇對象的類型 Autodesk.AutoCAD.ApplicationServices.Application.ShowModalDialog(fse); //顯示對話框 if (fse.DialogResult == System.Windows.Forms.DialogResult.OK) { return fse.EntObjectId; } else { return ObjectId.Null; } } } else { return ObjectId.Null; } } //---------------------------------------------------------------------- public ObjectId SelectSurface() //選擇曲面 此處為多余的代碼 { return SelectEntity("曲面" , CivilApplication.ActiveDocument.GetSurfaceIds(), typeof(Surface)); } //---------------------------------------------------------------------- public ObjectId SelectAlignment() //選擇路線 { return SelectEntity("路線" , CivilApplication.ActiveDocument.GetAlignmentIds(), typeof(Alignment)); } } }
測試結果如下: