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(
"
选择" + typeName + "<或按回车键从列表中选择>");
opt.AllowNone = true;
opt.SetRejectMessage("
选定的图元必须属于类型:" + 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));
}
}
}
测试结果如下:

