Files
CDMUtility/CivilModelCreator/WpfCivilCreator.xaml.cs

476 lines
20 KiB
C#
Raw Permalink Normal View History

2026-02-23 14:35:54 +08:00
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
{
/// <summary>
/// WpfCivilCreator.xaml 的交互逻辑
/// </summary>
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<string> sheetli = new List<string>();
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<Element> 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<ElementId> 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();
}
}
/// <summary>
///
/// </summary>
/// <param name="isFirstRowColumn"></param>
/// <returns></returns>
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);
}
}
}
}
}