Files

272 lines
11 KiB
C#
Raw Permalink Normal View History

2026-02-23 14:35:54 +08:00
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);
}
}
}
}
}
}
}