Files
CDMUtility/CivilModelCreator/CmdCDMToExcel.cs
2026-02-23 14:35:54 +08:00

272 lines
11 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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);
}
}
}
}
}
}
}