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));
}
}
}
測試結果如下:

