272 lines
11 KiB
C#
272 lines
11 KiB
C#
using Autodesk.Revit.Attributes;
|
||
using Autodesk.Revit.DB;
|
||
using Autodesk.Revit.UI;
|
||
using Autodesk.Revit.UI.Selection;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Threading.Tasks;
|
||
|
||
namespace CivilModelCreator
|
||
{
|
||
[Transaction(TransactionMode.Manual)]
|
||
class CmdCDMToExcel : IExternalCommand
|
||
{
|
||
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
|
||
{
|
||
Autodesk.Revit.ApplicationServices.Application app = commandData.Application.Application;
|
||
Document doc = commandData.Application.ActiveUIDocument.Document;
|
||
VistaFolderBrowserDialog dialog = new VistaFolderBrowserDialog
|
||
{
|
||
Multiselect = false
|
||
};
|
||
dialog.ShowDialog();
|
||
if (dialog.SelectedPath == null)
|
||
{
|
||
return Result.Cancelled;
|
||
}
|
||
string path = dialog.SelectedPath;
|
||
|
||
|
||
|
||
|
||
var levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements();
|
||
|
||
|
||
#region 柱
|
||
|
||
List<CDMData> cdmData = NewMethod(doc, levels);
|
||
#endregion
|
||
|
||
#region 板
|
||
GetFloorsCDM(doc, levels, cdmData);
|
||
#endregion
|
||
|
||
var beams = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralFraming).OfClass(typeof(FamilyInstance)).ToElements();
|
||
foreach (FamilyInstance beam in beams)
|
||
{
|
||
CDMData cdm = new CDMData();
|
||
}
|
||
cdmData = cdmData.OrderBy(c => c.CategoryId).ThenBy(c => c.LevelName).ThenBy(c => c.Code).ToList();
|
||
try
|
||
{
|
||
CDMToExcelModeless model = new CDMToExcelModeless(path, cdmData);
|
||
model.ProgressModeless();
|
||
}
|
||
catch (Exception e)
|
||
{
|
||
|
||
if (!(e is Autodesk.Revit.Exceptions.OperationCanceledException))
|
||
{
|
||
message = e.Message;
|
||
return Result.Failed;
|
||
}
|
||
}
|
||
return Result.Succeeded;
|
||
}
|
||
|
||
private static List<CDMData> NewMethod(Document doc, IList<Element> levels)
|
||
{
|
||
var StColumns = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).OfClass(typeof(FamilyInstance)).ToElements();
|
||
|
||
Dictionary<ElementId, string> dicfsColoumn = new Dictionary<ElementId, string>();
|
||
int num = 1;
|
||
//查找所有具有实例的柱子类型及赋予编码
|
||
for (int i = 0; i < StColumns.Count(); i++)
|
||
{
|
||
ElementId fiId = ((FamilyInstance)StColumns[i]).Symbol.Id;
|
||
try
|
||
{
|
||
dicfsColoumn.Add(fiId, string.Format("0{0}", num));
|
||
num += 1;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
continue;
|
||
}
|
||
}
|
||
List<CDMData> cdmData = new List<CDMData>();
|
||
|
||
//将柱数据转成cdm数据
|
||
foreach (FamilyInstance column in StColumns)
|
||
{
|
||
//cdm.SymbolId = column.GetTypeId();
|
||
//坐标
|
||
XYZ p1 = column.GetTotalTransform().Origin;
|
||
CDMData cdm = new CDMData
|
||
{
|
||
TypeId = column.Symbol.Id,
|
||
Center_X = p1.X * 304.8 / 1000,
|
||
Center_Y = p1.Y * 304.8 / 1000,
|
||
HcdmClass = "A2001",
|
||
Level = (Level)doc.GetElement(column.LevelId),
|
||
Name = column.Symbol.Family.Name + ":" + column.Symbol.Name,
|
||
Category = "柱",
|
||
|
||
};
|
||
dicfsColoumn.TryGetValue(column.Symbol.Id, out cdm.CategoryId);
|
||
//底部标高名称
|
||
string baselevelname = column.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).AsValueString();
|
||
//顶部标高名称
|
||
string toplevelname = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).AsValueString();
|
||
//var value = dict.Where(q => q.Key == column.Symbol.Id).Select(q => q.Value).FirstOrDefault();
|
||
//cdm.HcdmNumber = String.Format("{0}-{1}", value.ToString(), baselevelname);
|
||
|
||
foreach (Level lev in levels)
|
||
{
|
||
//以深度去布置柱子,底标高和顶标高相反
|
||
if (lev.Name == baselevelname)
|
||
{
|
||
//底部偏移
|
||
double baseoffest = column.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).AsDouble();
|
||
cdm.BaseLevel = UnitUtils.ConvertFromInternalUnits(lev.Elevation + baseoffest, DisplayUnitType.DUT_METERS);
|
||
//md.BaseLevel = lev.Elevation * 304.8 / 1000 + baseof;
|
||
}
|
||
if (lev.Name == toplevelname)
|
||
{
|
||
//顶部偏移
|
||
double topoffest = column.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).AsDouble();
|
||
cdm.TopLevel = UnitUtils.ConvertFromInternalUnits(lev.Elevation + topoffest, DisplayUnitType.DUT_METERS);
|
||
}
|
||
}
|
||
double b = 0;
|
||
double h = 0;
|
||
try
|
||
{
|
||
b = column.Symbol.LookupParameter("b").AsDouble();
|
||
h = column.Symbol.LookupParameter("h").AsDouble();
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
System.Windows.MessageBox.Show(ex.Message);
|
||
}
|
||
cdm.Length = UnitUtils.ConvertFromInternalUnits(b, DisplayUnitType.DUT_METERS);
|
||
cdm.Width = UnitUtils.ConvertFromInternalUnits(h, DisplayUnitType.DUT_METERS);
|
||
cdmData.Add(cdm);
|
||
|
||
//md.Length=from Parameter para in fi.Parameters
|
||
// where para.Definition.Name=="b"
|
||
// select
|
||
//md.Length=fi.get_Parameter()
|
||
|
||
|
||
}
|
||
//层构件编号
|
||
for (int i = 0; i < levels.Count(); i++)
|
||
{
|
||
for (int j = 0; j < dicfsColoumn.Count; j++)
|
||
{
|
||
ElementId id = dicfsColoumn.ElementAt(j).Key;
|
||
//归类cdm中同标高同类型
|
||
IEnumerable<CDMData> targetcdm = from d in cdmData
|
||
where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id)
|
||
select d;
|
||
//排序
|
||
List<CDMData> li = targetcdm.OrderByDescending(c => c.Center_Y).ThenBy(c => c.Center_X).ToList();
|
||
//var li = targetcdm.ToList();
|
||
//IEnumerable<CDMData> enuCdm = from cdm in targetcdm
|
||
// orderby cdm.Center_Y
|
||
// select cdm;
|
||
//li.Sort();
|
||
//while (itr.MoveNext)
|
||
//{
|
||
// Element e = (Element)itr.Current;
|
||
|
||
//}
|
||
for (int k = 0; k < li.ToList().Count; k++)
|
||
{
|
||
if (k > 8)
|
||
{
|
||
li[k].Code = string.Format("0{0}", k + 1);
|
||
}
|
||
else
|
||
{
|
||
li[k].Code = string.Format("00{0}", k + 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
return cdmData;
|
||
}
|
||
|
||
private static void GetFloorsCDM(Document doc, IList<Element> levels, List<CDMData> cdmData)
|
||
{
|
||
var floors = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).OfClass(typeof(Floor)).ToElements();
|
||
|
||
Dictionary<ElementId, string> dicFloors = new Dictionary<ElementId, string>();
|
||
int num1 = 1;
|
||
for (int i = 0; i < floors.Count; i++)
|
||
{
|
||
ElementId flId = floors[i].GetTypeId();
|
||
try
|
||
{
|
||
dicFloors.Add(flId, string.Format("0{0}", num1));
|
||
num1 += 1;
|
||
}
|
||
catch (Exception)
|
||
{
|
||
|
||
continue;
|
||
}
|
||
}
|
||
|
||
foreach (Floor floor in floors)
|
||
{
|
||
View3D v = (View3D)doc.ActiveView;
|
||
if (v == null)
|
||
{
|
||
System.Windows.MessageBox.Show("请使用三维视图");
|
||
}
|
||
XYZ max = floor.get_BoundingBox(v).Max;
|
||
XYZ min = floor.get_BoundingBox(v).Min;
|
||
XYZ p = (max + min) / 2;
|
||
CDMData cdm = new CDMData
|
||
{
|
||
Level = (Level)doc.GetElement(floor.LevelId),
|
||
TypeId = floor.FloorType.Id,
|
||
HcdmClass = "A2002",
|
||
Center_X = p.X * 304.8 / 1000,
|
||
Center_Y = p.Y * 304.8 / 1000,
|
||
Length = UnitUtils.ConvertFromInternalUnits(max.X - min.X, DisplayUnitType.DUT_METERS),
|
||
Width = UnitUtils.ConvertFromInternalUnits(max.Y - min.Y, DisplayUnitType.DUT_METERS),
|
||
BaseLevel = Convert.ToDouble(floor.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_BOTTOM).AsValueString()) / 1000,
|
||
TopLevel = Convert.ToDouble(floor.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_TOP).AsValueString()) / 1000,
|
||
Name = floor.FloorType.FamilyName + ":" + floor.Name,
|
||
Category = "板",
|
||
};
|
||
dicFloors.TryGetValue(floor.FloorType.Id, out cdm.CategoryId);
|
||
cdmData.Add(cdm);
|
||
|
||
}
|
||
|
||
for (int i = 0; i < levels.Count(); i++)
|
||
{
|
||
for (int j = 0; j < dicFloors.Count; j++)
|
||
{
|
||
ElementId id = dicFloors.ElementAt(j).Key;
|
||
//归类cdm中同标高同类型
|
||
IEnumerable<CDMData> targetcdm = from d in cdmData
|
||
where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id)
|
||
select d;
|
||
//排序
|
||
//var li = targetcdm.ToList();
|
||
List<CDMData> li = targetcdm.OrderByDescending(c => c.Center_Y).ThenBy(c => c.Center_X).ToList();
|
||
for (int k = 0; k < li.Count; k++)
|
||
{
|
||
if (k > 8)
|
||
{
|
||
li[k].Code = string.Format("0{0}", k + 1);
|
||
}
|
||
else
|
||
{
|
||
li[k].Code = string.Format("00{0}", k + 1);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|