using System; using System.IO; using System.Linq; using System.Text; using System.Data; using System.Collections; using System.Windows.Forms; using System.Collections.Generic; using System.Data.OleDb; using Autodesk.Revit; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Mechanical; using Autodesk.Revit.DB.Plumbing; using Autodesk.Revit.DB.Electrical; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; using Autodesk.Revit.Creation; using Autodesk.Revit.DB.Structure; namespace EarthLayerModel { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class EarthLayerModel : IExternalCommand { public Result Execute(Autodesk.Revit.UI.ExternalCommandData CommandData, ref string Message, ElementSet elementset) { int page_index = 1; //页面,每个excel文件不一样,应该要做个窗口下拉。从1算起。 int x_column = 19; int y_column = 18; int z_column = 2; //“孔口标高” int begin_row = 3; //从第几行开始是正式坐标数据。从1算起。 MessageBox.Show("当前Z坐标使用孔口绝对坐标。" + "\n" + "OK", "向日葵", MessageBoxButtons.OK); Autodesk.Revit.ApplicationServices.Application Revit = CommandData.Application.Application; Autodesk.Revit.UI.UIDocument uidoc = CommandData.Application.ActiveUIDocument; Autodesk.Revit.DB.Document doc = CommandData.Application.ActiveUIDocument.Document; ICollection currentselectid = uidoc.Selection.GetElementIds(); Autodesk.Revit.DB.View curview = doc.ActiveView; string tmppath = System.IO.Path.GetTempPath(); List delfile_list = new List(); #region//求实体填充 ElementId solidid = ElementId.InvalidElementId; IList fplist = (new FilteredElementCollector(doc)).OfClass(typeof(FillPatternElement)).ToElements(); foreach (Element ee in fplist) { if (ee.Name == "实体填充") { solidid = ee.Id; break; } if (solidid == ElementId.InvalidElementId) { MessageBox.Show("找不到名为“实体填充”的填充样式,请先新建一个。", "向日葵", MessageBoxButtons.OK); return Autodesk.Revit.UI.Result.Succeeded; } } #endregion TransactionStatus status = TransactionStatus.Uninitialized; TransactionGroup transGroup = new TransactionGroup(doc, "地质建模"); if (transGroup.Start() == TransactionStatus.Started) { #region//加共享参数-常规模型 String newfName = Revit.RecordingJournalFilename; string sharepara_txt = "*META VERSION MINVERSION" + "\r\n"; sharepara_txt += "META 2 1" + "\r\n"; sharepara_txt += "*GROUP ID NAME" + "\r\n"; sharepara_txt += "GROUP 1 地质参数" + "\r\n"; sharepara_txt += "*PARAM GUID NAME DATATYPE DATACATEGORY GROUP VISIBLE DESCRIPTION USERMODIFIABLE" + "\r\n"; sharepara_txt += "PARAM" + "\t" + "11b28335-372f-479d-acf5-ddc3103cd76d" + "\t" + "孔号1" + " TEXT 1 1 1" + "\r\n"; sharepara_txt += "PARAM" + "\t" + "64331fcb-5a1c-4f30-bc6c-4fae29921a9e" + "\t" + "孔号2" + " TEXT 1 1 1" + "\r\n"; sharepara_txt += "PARAM" + "\t" + "85345026-1981-45b9-b1fb-460805a7d924" + "\t" + "孔号3" + " TEXT 1 1 1" + "\r\n"; String fName = newfName.Substring(0, newfName.LastIndexOf("\\")) + "\\地质建模Para.txt"; StreamWriter sw = new StreamWriter(fName, false, Encoding.Unicode); sw.Write(sharepara_txt); sw.Close(); Revit.SharedParametersFilename = fName; DefinitionFile sharedParametersFile_gm = Revit.OpenSharedParameterFile(); DefinitionGroup group_gm = sharedParametersFile_gm.Groups.get_Item("地质参数"); CategorySet catSet_gm = Revit.Create.NewCategorySet(); catSet_gm.Insert(doc.Settings.Categories.get_Item(BuiltInCategory.OST_GenericModel)); Autodesk.Revit.DB.Binding binding_gm = Revit.Create.NewInstanceBinding(catSet_gm); Transaction transaction21 = new Transaction(doc, "共享参数"); transaction21.Start(); foreach (Definition df in group_gm.Definitions) doc.ParameterBindings.Insert(df, binding_gm); transaction21.Commit(); #endregion string pathstring = ""; OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "选择Excel文件…"; openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);//桌面路径 //注意这里写路径时要用c:\\而不是c:\ openFileDialog.Filter = "文本文件|*.xls"; openFileDialog.RestoreDirectory = true; openFileDialog.FilterIndex = 1; if (openFileDialog.ShowDialog() == DialogResult.OK) pathstring = openFileDialog.FileName; else return Result.Succeeded; Microsoft.Office.Interop.Excel.Workbook wb = null; Microsoft.Office.Interop.Excel.Worksheet ws = null; ArrayList columnArr = new ArrayList();//列字段表 DataSet myDs = new DataSet(); System.Data.DataTable xlsTable = myDs.Tables.Add("show"); object missing = System.Reflection.Missing.Value; Microsoft.Office.Interop.Excel.Application excel = new Microsoft.Office.Interop.Excel.Application();//lauch excel application if (excel != null) { excel.Visible = true; //excel.UserControl = true; // 以只读的形式打开EXCEL文件 wb = excel.Workbooks.Open(pathstring, missing, true, missing, missing, missing, missing, missing, missing, true, missing, missing, missing, missing, missing); ws = (Microsoft.Office.Interop.Excel.Worksheet)wb.Worksheets.get_Item(page_index); //取得总记录行数(包括标题列) int rowsint = ws.UsedRange.Rows.Count; //得到行数 //int rowsint = begin_row + 2*50; int columnsint = ws.UsedRange.Columns.Count;//得到列数 List name_list = new List(); //string值集合(用来区分过滤器) List kh_list = new List(); //孔号集合 List point_list = new List(); List> str_list_list = new List>(); //每一个点对应有一列string List> point_list_list = new List>(); //每一个点对应有一列点,Z坐标不同 for (int m = begin_row; m <= rowsint; m++) { if (ws.Cells[m, z_column].Text == "") continue; if (m / 2 != (m + 1) / 2) //m为奇数 { List newstring_list = new List(); List newpoint_list = new List(); double x = 0; double y = 0; try { x = double.Parse((ws.Cells[m, x_column]).Text) * 1000 / 304.8; y = double.Parse((ws.Cells[m, y_column]).Text) * 1000 / 304.8; double z = double.Parse((ws.Cells[m, z_column]).Text) * 1000 / 304.8; point_list.Add(new XYZ(x, y, z)); newpoint_list.Add(new XYZ(x, y, z)); } catch { MessageBox.Show(m + "\n" + (ws.Cells[m, x_column]).Text + "\n" + (ws.Cells[m, y_column]).Text + "\n" + (ws.Cells[m, z_column]).Text, "向日葵", MessageBoxButtons.OK); continue; } //第i个string对应第i个点与第i+1个点 for (int n = z_column + 1; n < Math.Min(x_column,y_column); n++) { if (ws.Cells[m, n].Text != "") { if (!name_list.Contains(ws.Cells[m, n].Text)) name_list.Add(ws.Cells[m, n].Text); newstring_list.Add(ws.Cells[m, n].Text); try { //double zp = z + double.Parse((ws.Cells[m + 1, n]).Text) * 1000 / 304.8; //相对Z坐标 double zp = double.Parse((ws.Cells[m + 1, n]).Text) * 1000 / 304.8; //绝对Z坐标 newpoint_list.Add(new XYZ(x, y, zp)); } catch { MessageBox.Show(m + "\n" + (ws.Cells[m + 1, n]).Text, "向日葵", MessageBoxButtons.OK); } } } str_list_list.Add(newstring_list); point_list_list.Add(newpoint_list); kh_list.Add(ws.Cells[m, 1].Text); } } //求包络外框 double x_min = point_list[0].X; double x_max = point_list[0].X; double y_min = point_list[0].Y; double y_max = point_list[0].Y; double z_mmm = point_list[0].Z + 1000/304.8; foreach (XYZ p in point_list) { if (p.X > x_max) x_max = p.X; if (p.X < x_min) x_min = p.X; if (p.Y > y_max) y_max = p.Y; if (p.Y < y_min) y_min = p.Y; } x_min -= 20000 / 304.8; y_min -= 20000 / 304.8; x_max += 20000 / 304.8; y_max += 20000 / 304.8; XYZ left_bottom = new XYZ(x_min, y_min, z_mmm); XYZ right_top = new XYZ(x_max, y_max, z_mmm); //建楼板 Curve c1 = Line.CreateBound(new XYZ(x_min, y_min, z_mmm), new XYZ(x_max, y_min, z_mmm)); Curve c2 = Line.CreateBound(new XYZ(x_max, y_min, z_mmm), new XYZ(x_max, y_max, z_mmm)); Curve c3 = Line.CreateBound(new XYZ(x_max, y_max, z_mmm), new XYZ(x_min, y_max, z_mmm)); Curve c4 = Line.CreateBound(new XYZ(x_min, y_max, z_mmm), new XYZ(x_min, y_min, z_mmm)); CurveArray ca = new CurveArray(); ca.Append(c1); ca.Append(c2); ca.Append(c3); ca.Append(c4); Transaction transaction = new Transaction(doc, "yy"); transaction.Start(); Floor floor = doc.Create.NewFloor(ca, true); transaction.Commit(); //求三角剖分 Transaction transaction2 = new Transaction(doc, "yy"); FailureHandlingOptions failureHandlingOptions2 = transaction2.GetFailureHandlingOptions(); FailureHandler failureHandler2 = new FailureHandler(); failureHandlingOptions2.SetFailuresPreprocessor(failureHandler2); failureHandlingOptions2.SetClearAfterRollback(true); transaction2.SetFailureHandlingOptions(failureHandlingOptions2); transaction2.Start(); int k = -1; foreach (XYZ p in point_list) { k = (-1) * k; XYZ newp = new XYZ(p.X, p.Y, p.Z + k * 1000 / 304.8); SlabShapeEditor sse = floor.SlabShapeEditor; sse.DrawPoint(newp); } transaction2.Commit(); List curve_list = new List(); SlabShapeEditor sse_ok = floor.SlabShapeEditor; foreach (SlabShapeCrease ssc in sse_ok.SlabShapeCreases) { Curve cc = Line.CreateBound(new XYZ(ssc.Curve.GetEndPoint(0).X, ssc.Curve.GetEndPoint(0).Y, 0), new XYZ(ssc.Curve.GetEndPoint(1).X, ssc.Curve.GetEndPoint(1).Y, 0)); curve_list.Add(cc); } //求三角面 for (int i = 0; i <= point_list.Count - 3; i++) { for (int t = i+1; t <= point_list.Count - 2; t++) { XYZ p1 = point_list[i]; XYZ p2 = point_list[t]; XYZ p10 = new XYZ(p1.X, p1.Y, 0); XYZ p20 = new XYZ(p2.X, p2.Y, 0); if (p10.DistanceTo(p20) > 50000 / 304.8) //大于50米不考虑连接 continue; for (int r = t + 1; r <= point_list.Count - 1; r++) { XYZ p3 = point_list[r]; XYZ p30 = new XYZ(p3.X, p3.Y, 0); if (p30.DistanceTo(p10) > 50000 / 304.8 || p30.DistanceTo(p20) > 50000 / 304.8) //大于50米不考虑连接 continue; Curve ctmp1 = null; Curve ctmp2 = null; Curve ctmp3 = null; for (int a = 0; a <= curve_list.Count - 1; a++) { if (curve_list[a].GetEndPoint(0).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(1).DistanceTo(p20) < 0.01) ctmp1 = curve_list[a]; if (curve_list[a].GetEndPoint(1).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(0).DistanceTo(p20) < 0.01) ctmp1 = curve_list[a]; if (curve_list[a].GetEndPoint(0).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(1).DistanceTo(p30) < 0.01) ctmp2 = curve_list[a]; if (curve_list[a].GetEndPoint(1).DistanceTo(p10) < 0.01 && curve_list[a].GetEndPoint(0).DistanceTo(p30) < 0.01) ctmp2 = curve_list[a]; if (curve_list[a].GetEndPoint(0).DistanceTo(p20) < 0.01 && curve_list[a].GetEndPoint(1).DistanceTo(p30) < 0.01) ctmp3 = curve_list[a]; if (curve_list[a].GetEndPoint(1).DistanceTo(p20) < 0.01 && curve_list[a].GetEndPoint(0).DistanceTo(p30) < 0.01) ctmp3 = curve_list[a]; } if (ctmp1 != null && ctmp2 != null && ctmp3 != null) { //现在有三个int:i、t、r,互相连接 List xyz_i = point_list_list[i]; List xyz_t = point_list_list[t]; List xyz_r = point_list_list[r]; List str_i = str_list_list[i]; List str_t = str_list_list[t]; List str_r = str_list_list[r]; //string stri = ""; //foreach (string s in str_i) // stri += s + "_"; //string strt = ""; //foreach (string s in str_t) // strt += s + "_"; //string strr = ""; //foreach (string s in str_r) // strr += s + "_"; //MessageBox.Show(str_i.Count + "\n" + str_t.Count + "\n" + str_r.Count, "向日葵", MessageBoxButtons.OK); //MessageBox.Show(stri + "\n" + strt + "\n" + strr, "向日葵", MessageBoxButtons.OK); Boolean ok = false; do { ok = true; int mincount = Math.Min(Math.Min(str_i.Count, str_t.Count), str_r.Count); for (int x = 0; x <= mincount - 1; x++) { if (str_i[x] == str_t[x] && str_i[x] != str_r[x]) { str_r.Insert(x, str_t[x]); xyz_r.Insert(x, xyz_r[x]); //重复上一点 ok = false; continue; } if (str_i[x] != str_t[x] && str_i[x] == str_r[x]) { str_t.Insert(x, str_i[x]); xyz_t.Insert(x, xyz_t[x]); //重复上一点 ok = false; continue; } if (str_i[x] != str_t[x] && str_t[x] == str_r[x]) { str_i.Insert(x, str_r[x]); xyz_i.Insert(x, xyz_i[x]); //重复上一点 ok = false; continue; } if (str_i[x] != str_t[x] && str_t[x] != str_r[x] && str_i[x] != str_r[x]) { str_t.Insert(x, str_i[x]); xyz_t.Insert(x, xyz_t[x]); //重复上一点 str_r.Insert(x, str_i[x]); xyz_r.Insert(x, xyz_r[x]); //重复上一点 ok = false; continue; } //最后补齐三列数据使其等长 if (str_i.Count == x+1 && str_t.Count > x+1) { str_i.Add(str_t[x + 1]); xyz_i.Add(xyz_i[x + 1]); //重复上一点 ok = false; continue; } if (str_i.Count == x+1 && str_r.Count > x+1) { str_i.Add(str_r[x + 1]); xyz_i.Add(xyz_i[x + 1]); //重复上一点 ok = false; continue; } if (str_t.Count == x+1 && str_i.Count > x+1) { str_t.Add(str_i[x + 1]); xyz_t.Add(xyz_t[x + 1]); //重复上一点 ok = false; continue; } if (str_t.Count == x+1 && str_r.Count > x+1) { str_t.Add(str_r[x + 1]); xyz_t.Add(xyz_t[x + 1]); //重复上一点 ok = false; continue; } if (str_r.Count == x+1 && str_t.Count > x+1) { str_r.Add(str_t[x + 1]); xyz_r.Add(xyz_r[x + 1]); //重复上一点 ok = false; continue; } if (str_r.Count == x+1 && str_i.Count > x+1) { str_r.Add(str_i[x + 1]); xyz_r.Add(xyz_r[x + 1]); //重复上一点 ok = false; continue; } } } while (ok == false); //string stri2 = ""; //foreach (string s in str_i) // stri2 += s + "_"; //string strt2 = ""; //foreach (string s in str_t) // strt2 += s + "_"; //string strr2 = ""; //foreach (string s in str_r) // strr2 += s + "_"; //MessageBox.Show(stri2 + "\n" + strt2 + "\n" + strr2, "向日葵", MessageBoxButtons.OK); //string xyzi2 = ""; //foreach (XYZ p in xyz_i) // xyzi2 += p.Z*304.8 + "_"; //string xyzt2 = ""; //foreach (XYZ p in xyz_t) // xyzt2 += p.Z * 304.8 + "_"; //string xyzr2 = ""; //foreach (XYZ p in xyz_r) // xyzr2 += p.Z * 304.8 + "_"; //MessageBox.Show(xyzi2 + "\n" + xyzt2 + "\n" + xyzr2, "向日葵", MessageBoxButtons.OK); List int_i = new List(); //记录已生成的段落 List int_t = new List(); List int_r = new List(); if (str_i.Count < 2) continue; for (int si = 0; si <= str_i.Count - 1; si++) { XYZ delta = xyz_i[si]; XYZ p1a = xyz_i[si] - delta; XYZ p2a = xyz_t[si] - delta; XYZ p3a = xyz_r[si] - delta; XYZ p1b = xyz_i[si + 1] - delta; XYZ p2b = xyz_t[si + 1] - delta; XYZ p3b = xyz_r[si + 1] - delta; if (p1a.IsAlmostEqualTo(p1b) && p2a.IsAlmostEqualTo(p2b) && p3a.IsAlmostEqualTo(p3b)) //为什么会有这种情况? continue; if (p1a.IsAlmostEqualTo(p1b)) p1b += new XYZ(0, 0, -0.01); if (p2a.IsAlmostEqualTo(p2b)) p2b += new XYZ(0, 0, -0.01); if (p3a.IsAlmostEqualTo(p3b)) p3b += new XYZ(0, 0, -0.01); Curve curve1a = Line.CreateBound(p1a, p2a); Curve curve2a = Line.CreateBound(p2a, p3a); Curve curve3a = Line.CreateBound(p3a, p1a); Curve curve1b = Line.CreateBound(p1b, p2b); Curve curve2b = Line.CreateBound(p2b, p3b); Curve curve3b = Line.CreateBound(p3b, p1b); CurveLoop cla = new CurveLoop(); CurveLoop clb = new CurveLoop(); cla.Append(curve1a); cla.Append(curve2a); cla.Append(curve3a); clb.Append(curve1b); clb.Append(curve2b); clb.Append(curve3b); Solid solid = null; try { solid = GeometryCreationUtilities.CreateBlendGeometry(cla, clb, null); } catch { } if (solid == null) continue; //做族 string templateFileName = Revit.FamilyTemplatePath + "\\公制常规模型.rft"; Autodesk.Revit.DB.Document familydoc_gd = Revit.NewFamilyDocument(templateFileName); Autodesk.Revit.Creation.FamilyItemFactory creationFamily_gd = familydoc_gd.FamilyCreate; Transaction transactionff = new Transaction(familydoc_gd, "yy"); transactionff.Start(); Element e = FreeFormElement.Create(familydoc_gd, solid); transactionff.Commit(); string tmp_fName = tmppath; tmp_fName += "\\地质" + str_i[si] + "层_" + kh_list[i] + "_" + kh_list[t] + "_" + kh_list[r] + "_"; tmp_fName += si.ToString() + ".rfa"; try { familydoc_gd.SaveAs(tmp_fName); } catch { } familydoc_gd.Close(false); delfile_list.Add(tmp_fName); Transaction transaction23 = new Transaction(doc, "yy"); transaction23.Start(); doc.LoadFamily(tmp_fName); transaction23.Commit(); string familyname = tmp_fName.Substring(tmp_fName.LastIndexOf("\\") + 1, tmp_fName.Length - tmp_fName.LastIndexOf("\\") - 5); IEnumerable familysymbols = from elem in new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)) let fstmp = elem as FamilySymbol where fstmp.Name == familyname select fstmp; FamilySymbol symbol = doc.GetElement(familysymbols.First().Id) as FamilySymbol; Transaction transaction82 = new Transaction(doc, "yy"); transaction82.Start(); symbol.Activate(); transaction82.Commit(); Transaction transaction8 = new Transaction(doc, "yy"); transaction8.Start(); FamilyInstance fi = doc.Create.NewFamilyInstance(delta, symbol, curview.GenLevel, StructuralType.NonStructural); transaction8.Commit(); Transaction transaction9 = new Transaction(doc, "yy"); transaction9.Start(); fi.LookupParameter("注释").Set(str_i[si]); fi.LookupParameter("孔号1").Set(kh_list[i]); fi.LookupParameter("孔号2").Set(kh_list[t]); fi.LookupParameter("孔号3").Set(kh_list[r]); transaction9.Commit(); } } } } } ICollection categories = new List(); foreach (Category c in doc.Settings.Categories) { BuiltInCategory bic = (BuiltInCategory)c.Id.IntegerValue; if (c.Name == "常规模型") categories.Add(c.Id); } //加过滤器 for (int i = 0; i < name_list.Count; i++) { string str = name_list[i]; FilterRule fr = null; try { fr = ParameterFilterRuleFactory.CreateEqualsRule(new ElementId(-1010106), str, true); } catch { continue; } List fr_list = new List(); fr_list.Add(fr); Transaction transaction00 = new Transaction(doc, "yy"); transaction00.Start(); try { ParameterFilterElement pf = ParameterFilterElement.Create(doc, str, categories, fr_list); Random RandomNum_First = new Random((int)DateTime.Now.Ticks); System.Threading.Thread.Sleep(RandomNum_First.Next(50)); Random RandomNum_Sencond = new Random((int)DateTime.Now.Ticks); // 为了在白色背景上显示,尽量生成深色 int int_Red = RandomNum_First.Next(256); int int_Green = RandomNum_Sencond.Next(256); int int_Blue = (int_Red + int_Green > 400) ? 0 : 400 - int_Red - int_Green; int_Blue = (int_Blue > 255) ? 255 : int_Blue; OverrideGraphicSettings ogs = new OverrideGraphicSettings(); ogs.SetProjectionLineColor(new Autodesk.Revit.DB.Color(0, 0, 0)); ogs.SetProjectionLinePatternId(ElementId.InvalidElementId); ogs.SetProjectionFillColor(new Autodesk.Revit.DB.Color((byte)int_Red, (byte)int_Green, (byte)int_Blue)); ogs.SetProjectionFillPatternId(solidid); curview.AddFilter(pf.Id); curview.SetFilterVisibility(pf.Id, true); curview.SetFilterOverrides(pf.Id, ogs); } catch { } transaction00.Commit(); } Transaction transaction1 = new Transaction(doc, "yy"); transaction1.Start(); curview.DisplayStyle = DisplayStyle.ShadingWithEdges; transaction1.Commit(); } excel.Quit(); excel = null; } status = transGroup.Assimilate(); foreach (string delpath in delfile_list) { System.IO.File.Delete(delpath); } return Result.Succeeded; } //public } public class FailureHandler : IFailuresPreprocessor { public string ErrorMessage { set; get; } public string ErrorSeverity { set; get; } public FailureHandler() { ErrorMessage = ""; ErrorSeverity = ""; } public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor) { IList failureMessages = failuresAccessor.GetFailureMessages(); foreach (FailureMessageAccessor failureMessageAccessor in failureMessages) { FailureDefinitionId id = failureMessageAccessor.GetFailureDefinitionId(); try { ErrorMessage = failureMessageAccessor.GetDescriptionText(); } catch { ErrorMessage = "Unknown Error"; } try { FailureSeverity failureSeverity = failureMessageAccessor.GetSeverity(); ErrorSeverity = failureSeverity.ToString(); if (failureSeverity == FailureSeverity.Warning) { failuresAccessor.DeleteWarning(failureMessageAccessor); } else { failuresAccessor.ResolveFailure(failureMessageAccessor); return FailureProcessingResult.ProceedWithCommit; } } catch { } } return FailureProcessingResult.Continue; } } }