using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; using Microsoft.Win32; using NPOI.HSSF.UserModel; using NPOI.SS.UserModel; using NPOI.XSSF.UserModel; using System; using System.Collections; using System.Collections.Generic; using System.Data; using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace CivilModelCreator { /// /// WpfCivilCreator.xaml 的交互逻辑 /// public partial class WpfCivilCreator { Document doc; Autodesk.Revit.ApplicationServices.Application app; IWorkbook workbook = null; DataTable dt = new DataTable(); string famPath; Family fam; Document famdoc; public WpfCivilCreator(Autodesk.Revit.ApplicationServices.Application app, Document doc) { this.doc = doc; this.app = app; InitializeComponent(); } private void BtnExcelPath_Click(object sender, RoutedEventArgs e) { string filter = "读取Excel(*.xlsx;*.xls)|*.xlsx;*.xls"; OpenFileDialog openDialog = new OpenFileDialog(); openDialog.Filter = filter; openDialog.Title = "选择Excel文件"; if (openDialog.ShowDialog() == true) { var path = openDialog.FileName; if (path != null) { tbExcelPath.Text = path; using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) { if (path.IndexOf(".xlsx") > 0) // 2007版本 workbook = new XSSFWorkbook(fs); else if (path.IndexOf(".xls") > 0) // 2003版本 workbook = new HSSFWorkbook(fs); } int SheetCount = workbook.NumberOfSheets; List sheetli = new List(); for (int i = 0; i < SheetCount; i++) { sheetli.Add(workbook.GetSheetName(i)); } CBSheetName.ItemsSource = sheetli; } } } private void BtnCreater_Click(object sender, RoutedEventArgs e) { ModelType mt = new ModelType(); Level level = null; IList levels = new FilteredElementCollector(doc).OfClass(typeof(Level)).ToElements(); foreach (Level l in levels) { if (l.Name == "标高 1") { level = l; break; } } if (CBType.SelectedItem != null && CBSheetName.SelectedItem != null) { mt = (ModelType)CBType.SelectedIndex; switch (mt) { case ModelType.墙: break; case ModelType.梁: //PlaceBeam(); break; case ModelType.板: if (tbExcelPath != null) { PlaceFloors(level); } break; case ModelType.柱: if (tbExcelPath != null && tbRfaPath != null) { //ColumnAddParas(famPath); PlaceColumns(level); } break; default: break; } } } private CurveArray Skeptch(double x, double y, double l, double w) { XYZ cp = new XYZ(x, y, 0); XYZ p1 = new XYZ(x - l / 2, y + w / 2, 0); XYZ p2 = new XYZ(x + l / 2, y + w / 2, 0); XYZ p3 = new XYZ(x + l / 2, y - w / 2, 0); XYZ p4 = new XYZ(x - l / 2, y - w / 2, 0); Autodesk.Revit.DB.Line line1 = Autodesk.Revit.DB.Line.CreateBound(p1, p2); Autodesk.Revit.DB.Line line2 = Autodesk.Revit.DB.Line.CreateBound(p2, p3); Autodesk.Revit.DB.Line line3 = Autodesk.Revit.DB.Line.CreateBound(p3, p4); Autodesk.Revit.DB.Line line4 = Autodesk.Revit.DB.Line.CreateBound(p4, p1); CurveArray skeptch = new CurveArray(); skeptch.Append(line1); skeptch.Append(line2); skeptch.Append(line3); skeptch.Append(line4); return skeptch; } private void PlaceFloors(Level level) { var fts = new FilteredElementCollector(doc).OfClass(typeof(FloorType)); FloorType defft = (FloorType)(new FilteredElementCollector(doc).OfClass(typeof(FloorType)).FirstOrDefault()); //Hashtable fts = new Hashtable(); using (Transaction trans = new Transaction(doc, "布置板")) { trans.Start(); for (int r = 1; r < dt.Rows.Count; r++) { //string typeName = dt.Rows[r][1].ToString(); //ft = fts[typeName] as FloorType; FloorType ft = null; try { ft = (FloorType)defft.Duplicate(dt.Rows[r][1].ToString()); } catch (Exception) { foreach (FloorType f in fts) { if (f.Name == dt.Rows[r][1].ToString()) { ft = f; } } } finally { double x = Convert.ToDouble(dt.Rows[r][6]) * 1000 / 304.8; double y = Convert.ToDouble(dt.Rows[r][7]) * 1000 / 304.8; double l = Convert.ToDouble(dt.Rows[r][8]) * 1000 / 304.8 ; double w = Convert.ToDouble(dt.Rows[r][9]) * 1000 / 304.8; double h = Convert.ToDouble(dt.Rows[r][10]) * 1000 / 304.8; double t = (Convert.ToDouble(dt.Rows[r][10]) - Convert.ToDouble(dt.Rows[r][5])) * 1000 / 304.8; Floor f = doc.Create.NewFloor(Skeptch(x, y, l, w), ft, level, true); var le = f.get_Parameter(BuiltInParameter.LEVEL_PARAM).Set(level.Id); var of = f.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).Set(h); } //var thick = f.get_Parameter(BuiltInParameter.FLOOR_ATTR_DEFAULT_THICKNESS_PARAM).Set(t); } trans.Commit(); } } private void PlaceBraces(Autodesk.Revit.DB.UV point2D1, Autodesk.Revit.DB.UV point2D2, Level baseLevel, Level topLevel, FamilySymbol braceType, bool isXDirection) { //get the start points and end points of location lines of two braces double topHeight = topLevel.Elevation; double baseHeight = baseLevel.Elevation; double middleElevation = (topHeight + baseHeight) / 2; double middleHeight = (topHeight - baseHeight) / 2; Autodesk.Revit.DB.XYZ startPoint = new Autodesk.Revit.DB.XYZ(point2D1.U, point2D1.V, middleElevation); Autodesk.Revit.DB.XYZ endPoint = new Autodesk.Revit.DB.XYZ(point2D2.U, point2D2.V, middleElevation); Autodesk.Revit.DB.XYZ middlePoint; if (isXDirection) { middlePoint = new Autodesk.Revit.DB.XYZ((point2D1.U + point2D2.U) / 2, point2D2.V, topHeight); } else { middlePoint = new Autodesk.Revit.DB.XYZ(point2D2.U, (point2D1.V + point2D2.V) / 2, topHeight); } //create two brace and set their location line StructuralType structuralType = StructuralType.Brace; Autodesk.Revit.DB.ElementId levelId = topLevel.Id; Autodesk.Revit.DB.ElementId startLevelId = baseLevel.Id; Autodesk.Revit.DB.ElementId endLevelId = topLevel.Id; Autodesk.Revit.DB.Line line1 = Autodesk.Revit.DB.Line.CreateBound(startPoint, middlePoint); if (!braceType.IsActive) braceType.Activate(); FamilyInstance firstBrace = doc.Create.NewFamilyInstance(line1, braceType, baseLevel, structuralType); Parameter referenceLevel1 = firstBrace.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM); if (null != referenceLevel1) { referenceLevel1.Set(levelId); } Autodesk.Revit.DB.Line line2 = Autodesk.Revit.DB.Line.CreateBound(endPoint, middlePoint); FamilyInstance secondBrace = doc.Create.NewFamilyInstance(line2, braceType, baseLevel, structuralType); Parameter referenceLevel2 = secondBrace.get_Parameter(BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM); if (null != referenceLevel2) { referenceLevel2.Set(levelId); } } private void PlaceBeams(Autodesk.Revit.DB.UV point2D1, Autodesk.Revit.DB.UV point2D2, Level baseLevel, Level topLevel, FamilySymbol beamType) { double height = topLevel.Elevation; Autodesk.Revit.DB.XYZ startPoint = new Autodesk.Revit.DB.XYZ(point2D1.U, point2D1.V, height); Autodesk.Revit.DB.XYZ endPoint = new Autodesk.Revit.DB.XYZ(point2D2.U, point2D2.V, height); Autodesk.Revit.DB.ElementId topLevelId = topLevel.Id; Autodesk.Revit.DB.Line line = Autodesk.Revit.DB.Line.CreateBound(startPoint, endPoint); StructuralType structuralType = Autodesk.Revit.DB.Structure.StructuralType.Beam; if (!beamType.IsActive) beamType.Activate(); doc.Create.NewFamilyInstance(line, beamType, topLevel, structuralType); } private void PlaceColumns(Level level) { //FilteredElementCollector col = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_StructuralColumns).OfClass(typeof(Family)); using (Transaction trans = new Transaction(doc, "布置柱")) { trans.Start(); ISet ids = fam.GetFamilySymbolIds(); //FamilySymbol familysy = doc.GetElement(fam.GetFamilySymbolIds().TakeWhile) as FamilySymbol for (int i = 1; i < dt.Rows.Count; i++) { for (int j = 0; j < ids.Count; j++) { FamilySymbol fs = (FamilySymbol)doc.GetElement(ids.ElementAt(j)); if (!fs.IsActive) fs.Activate();//设为Activate状态 if (fs != null && fs.Name == dt.Rows[i][1].ToString()) { double x = Convert.ToDouble(dt.Rows[i][6]) * 1000 / 304.8; double y = Convert.ToDouble(dt.Rows[i][7]) * 1000 / 304.8; double z = Convert.ToDouble(dt.Rows[i][5]) * 1000 / 304.8; double z0 = Convert.ToDouble(dt.Rows[i][10]) * 1000 / 304.8; XYZ p = new XYZ(x, y, z); FamilyInstance fi = doc.Create.NewFamilyInstance(p, fs, level, Autodesk.Revit.DB.Structure.StructuralType.Column); fi.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(level.Id); fi.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(level.Id); fi.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(z); fi.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(z0); //ColumnAttachment.AddColumnAttachment(doc, fi, level, 0, ColumnAttachmentCutStyle.None, ColumnAttachmentJustification.Minimum, z); //ColumnAttachment.AddColumnAttachment(doc, fi, level, 0, ColumnAttachmentCutStyle.None, ColumnAttachmentJustification.Tangent, z0); for (int k = 2; k < dt.Columns.Count; k++) { var para = fi.LookupParameter(dt.Columns[k].ToString()); para.Set(dt.Rows[i][k].ToString()); } } else { continue; //MessageBox.Show("不存在此类型的族。"); } } } trans.Commit(); } } /// /// /// /// /// private DataTable ExcelToDataTable(bool isFirstRowColumn) { ISheet sheet = null; DataTable data = new DataTable(); int startRow = 0; //IWorkbook workbook = null; string sheetName = CBSheetName.SelectedValue.ToString(); if (sheetName != null) { sheet = workbook.GetSheet(sheetName); if (sheet == null) //如果没有找到指定的sheetName对应的sheet,则尝试获取第一个sheet { sheet = workbook.GetSheetAt(0); } } else { sheet = workbook.GetSheetAt(0); } if (sheet != null) { IRow firstRow = sheet.GetRow(0); int cellCount = firstRow.LastCellNum; //一行最后一个cell的编号 即总的列数 if (isFirstRowColumn) { for (int i = firstRow.FirstCellNum; i < cellCount; ++i) { ICell cell = firstRow.GetCell(i); if (cell != null) { string cellValue = ""; switch (cell.CellType) { case NPOI.SS.UserModel.CellType.Unknown: cellValue = "Unknown"; break; case NPOI.SS.UserModel.CellType.Numeric: cellValue = cell.NumericCellValue.ToString(); break; case NPOI.SS.UserModel.CellType.String: cellValue = cell.StringCellValue; break; case NPOI.SS.UserModel.CellType.Formula: cellValue = cell.CellFormula.ToString(); break; case NPOI.SS.UserModel.CellType.Blank: cellValue = ""; break; case NPOI.SS.UserModel.CellType.Boolean: cellValue = cell.BooleanCellValue.ToString(); break; case NPOI.SS.UserModel.CellType.Error: cellValue = "Error"; break; default: break; } if (cellValue != null) { DataColumn column = new DataColumn(cellValue); data.Columns.Add(column); } } } startRow = sheet.FirstRowNum + 1; } else { startRow = sheet.FirstRowNum; } //最后一列的标号 //int rowCount = sheet.LastRowNum; int rowCount = sheet.PhysicalNumberOfRows; for (int i = startRow; i <= rowCount; ++i) { IRow row = sheet.GetRow(i); if (row == null) { continue; //没有数据的行默认是null        } DataRow dataRow = data.NewRow(); for (int j = row.FirstCellNum; j < cellCount; ++j) { if (row.GetCell(j) != null) //同理,没有数据的单元格都默认是null { dataRow[j] = row.GetCell(j).ToString(); } } data.Rows.Add(dataRow); } } return data; } private void CBSheetName_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (CBSheetName.SelectedItem != null) { dt = ExcelToDataTable(true); dataGrid.ItemsSource = dt.DefaultView; } } private void BtnRfaPath_Click(object sender, RoutedEventArgs e) { string filter = "载入族文件(*.rfa)|*.rfa"; OpenFileDialog openDialog = new OpenFileDialog(); openDialog.Filter = filter; openDialog.Title = "选择族文件"; if (openDialog.ShowDialog() == true) { famPath = openDialog.FileName; if (famPath != null) { tbRfaPath.Text = famPath; } } } private void ColumnAddParas(string path) { famdoc = app.OpenDocumentFile(path); //Document famdoc = app.OpenDocumentFile(path); if (famdoc.IsFamilyDocument) { using (Transaction trans = new Transaction(famdoc)) { trans.Start("新建族类型、参数"); FamilyManager fm = famdoc.FamilyManager; for (int i = 1; i < dt.Rows.Count; i++) { try { FamilyType ft = fm.NewType(dt.Rows[i][1].ToString()); fm.CurrentType = ft; foreach (FamilyParameter para in fm.Parameters) { //设置结构柱b if (para.Definition.Name == "b") { fm.Set(para, Convert.ToDouble(dt.Rows[i][8]) * 1000 / 304.8); } //设置结构柱h if (para.Definition.Name == "h") { fm.Set(para, Convert.ToDouble(dt.Rows[i][9]) * 1000 / 304.8); } ft.AsDouble(para); } } catch (Exception) { continue; } } for (int colindex = 2; colindex < dt.Columns.Count; colindex++) { FamilyParameter fp = fm.AddParameter(dt.Columns[colindex].ToString(), BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES, ParameterType.Text, true); } trans.Commit(); fam = famdoc.LoadFamily(doc); famdoc.Close(false); } } } } }