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 = 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 NewMethod(Document doc, IList levels) { var StColumns = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).OfClass(typeof(FamilyInstance)).ToElements(); Dictionary dicfsColoumn = new Dictionary(); 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 = new List(); //将柱数据转成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 targetcdm = from d in cdmData where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id) select d; //排序 List li = targetcdm.OrderByDescending(c => c.Center_Y).ThenBy(c => c.Center_X).ToList(); //var li = targetcdm.ToList(); //IEnumerable 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 levels, List cdmData) { var floors = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Floors).OfClass(typeof(Floor)).ToElements(); Dictionary dicFloors = new Dictionary(); 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 targetcdm = from d in cdmData where d.Level.Id.Equals(levels[i].Id) && d.TypeId.Equals(id) select d; //排序 //var li = targetcdm.ToList(); List 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); } } } } } } }