首页 > 技术文章 > 模拟内部命令:从文件创建纵断面

myzw 2018-02-12 14:14 原文

 

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

测试结果如下:


 

 

 

 

推荐阅读