模擬內部命令:從文件創建縱斷面


 

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));
        }
    }
}

測試結果如下:


 

 

 

 


免責聲明!

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



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