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 = 20; //XY通常是反的,这里是按真实的XY读取 int y_column = 19; int z_column = 2; //“孔口标高” int begin_row = 1; //从第几行开始是正式坐标数据。从1算起。 MessageBox.Show("当前Z坐标使用孔口相对坐标。" + "\n" + "OK", "向日葵", MessageBoxButtons.OK); //找两个孔口,用绝对坐标对应相对坐标。 //XYZ p1_abs = new XYZ(97447290 / 304.8, 15426770 / 304.8, 5000 / 304.8); //P1绝对坐标 //XYZ p2_abs = new XYZ(97508030 / 304.8, 15496130 / 304.8, 5000 / 304.8); //P2绝对坐标 //XYZ p1_relative = new XYZ(-26559.4706 / 304.8, -5303.8028 / 304.8, 0); //P1相对坐标 //XYZ p2_relative = new XYZ(65390.1059 / 304.8, 1436.5661 / 304.8, 0); //P2相对坐标 XYZ p1_abs = new XYZ(0, 0, 0); XYZ p2_abs = new XYZ(0, 0, 0); XYZ p1_relative = new XYZ(0, 0, 0); XYZ p2_relative = new XYZ(0, 0, 0); double angle = -Math.PI * (ang_of_vector(p1_relative, p2_relative) - ang_of_vector(p1_abs, p2_abs)) / 180; Transform tf = Transform.Identity; tf.Origin = p1_relative - p1_abs; tf.BasisX = XYZ.BasisX; tf.BasisY = XYZ.BasisY; tf.BasisZ = XYZ.BasisZ; Transform tf2 = Transform.Identity; tf2.Origin = XYZ.Zero; tf2.BasisX = new XYZ(Math.Cos(angle), Math.Sin(angle), 0); tf2.BasisY = new XYZ(-Math.Sin(angle), Math.Cos(angle), 0); tf2.BasisZ = XYZ.BasisZ; Transform tf3 = Transform.Identity; tf3.Origin = p1_relative - tf2.Inverse.OfPoint(p1_relative); tf3.BasisX = XYZ.BasisX; tf3.BasisY = XYZ.BasisY; tf3.BasisZ = XYZ.BasisZ; 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 //加载族 Transaction transaction = new Transaction(doc, "load the FamilySymbol"); transaction.Start(); IEnumerable familysymbols_bj = from elem in new FilteredElementCollector(doc).OfClass(typeof(FamilySymbol)) let fstmp = elem as FamilySymbol where fstmp.Name.Contains("钻孔标记") select fstmp; if (familysymbols_bj.Count() == 0) { MessageBox.Show("请先加载配套的“钻孔标记”族。", "向日葵", MessageBoxButtons.OK); status = transGroup.Assimilate(); return Result.Succeeded; } FamilySymbol fs_bj = doc.GetElement(familysymbols_bj.First().Id) as FamilySymbol; fs_bj.Activate(); transaction.Commit(); List solid_list = new List(); List layername_list = new List(); List index1_list = new List(); List index2_list = new List(); List index3_list = new List(); List kh1_list = new List(); List kh2_list = new List(); List kh3_list = new List(); List delta_list = new List(); List int_list = new List(); 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*10; 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; double z = 0; x = double.Parse((ws.Cells[m, x_column]).Text.Replace("Y=", "")) * 1000 / 304.8; y = double.Parse((ws.Cells[m, y_column]).Text.Replace("X=", "")) * 1000 / 304.8; z = double.Parse((ws.Cells[m, z_column]).Text) * 1000 / 304.8; //加上相对坐标转换 point_list.Add(tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, z))))); newpoint_list.Add(tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, z))))); //第i个string对应第i个点与第i+1个点 for (int n = z_column + 1; n < Math.Min(x_column, y_column); n++) { string name = ws.Cells[m, n].Text.ToString(); //try //{ // double test = 0; // if (!name.Contains("-")) // test = double.Parse(name); // else // test = double.Parse(name.ElementAt(0).ToString()); //奇怪,不能用""来过滤 //} //catch //{ // //MessageBox.Show(m + "\n" + n, "向日葵", MessageBoxButtons.OK); // continue; //} if (!(name.Contains("0") || name.Contains("1") || name.Contains("2") || name.Contains("3") || name.Contains("4") || name.Contains("5") || name.Contains("6") || name.Contains("7") || name.Contains("8") || name.Contains("9"))) continue; if (name == "") continue; //if (name == "1") // name += " 填土(填石)"; //if (name == "2") // name += " 淤泥"; //if (name == "3-1") // name += " 黏土"; //if (name == "3-2") // name += " 砾砂"; //if (name == "4") // name += " 砂质黏性土"; //if (name == "5-1") // name += " 全风化花岗岩"; //if (name == "5-2") // name += " 强风化花岗岩"; //if (name == "5-3") // name += " 中风化花岗岩"; //if (name == "5-4") // name += " 微风化花岗岩"; if (ws.Cells[m, n].Text != "") { if (!name_list.Contains(name)) name_list.Add(name); newstring_list.Add(name); 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(tf3.OfPoint(tf2.Inverse.OfPoint(tf.OfPoint(new XYZ(x, y, zp))))); } catch { //MessageBox.Show((ws.Cells[m, n]).Text + "\n" + m + "\n" + n, "向日葵", MessageBoxButtons.OK); } } } str_list_list.Add(newstring_list); point_list_list.Add(newpoint_list); kh_list.Add(ws.Cells[m, 1].Text); } } //MessageBox.Show(str_list_list[0][0] + "\n" + str_list_list[0][1], "向日葵", MessageBoxButtons.OK); //求包络外框 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 transaction40 = new Transaction(doc, "yy"); transaction40.Start(); Floor floor = doc.Create.NewFloor(ca, true); transaction40.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); } //先放标记 Transaction transaction35 = new Transaction(doc, "yy"); transaction35.Start(); for (int i = 0; i <= point_list.Count - 1; i++) { FamilyInstance fi_bj = doc.Create.NewFamilyInstance(point_list[i], fs_bj, StructuralType.NonStructural); fi_bj.LookupParameter("孔号").Set(kh_list[i]); } transaction35.Commit(); #region //地形建模 //求三角面 List itr_list = new List(); 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,互相连接 int[] itr = new int[3]; itr[0] = i; itr[1] = t; itr[2] = r; itr_list.Add(itr); } } } } foreach (int[] itr in itr_list) { int i = itr[0]; int t = itr[1]; int r = itr[2]; 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]; List int_i_list = new List(); //i列已经用了的index List int_t_list = new List(); //t列已经用了的index List int_r_list = new List(); //r列已经用了的index //汇总三个点的所有Z坐标,排序 List z_list = new List(); foreach (XYZ p in xyz_i) { Boolean add = true; foreach (double d in z_list) { if (Math.Abs(d - p.Z) < 0.001) { add = false; break; } } if (add) z_list.Add(p.Z); } foreach (XYZ p in xyz_t) { Boolean add = true; foreach (double d in z_list) { if (Math.Abs(d - p.Z) < 0.001) { add = false; break; } } if (add) z_list.Add(p.Z); } foreach (XYZ p in xyz_r) { Boolean add = true; foreach (double d in z_list) { if (Math.Abs(d - p.Z) < 0.001) { add = false; break; } } if (add) z_list.Add(p.Z); } z_list.Sort(); z_list.Reverse(); //MessageBox.Show(z_list[0]*304.8 + "\n" + z_list[1] * 304.8, "向日葵", MessageBoxButtons.OK); //MessageBox.Show(xyz_i[0].Z * 304.8 + "\n" + xyz_i[1].Z * 304.8, "向日葵", MessageBoxButtons.OK); //从高到低依次检测各点 for (int q = 0; q < z_list.Count; q++) { int index_i = -1; int index_ii = -1; int index_t = -1; int index_tt = -1; int index_r = -1; int index_rr = -1; string layername = ""; double dd = z_list[q]; for (int y = 0; y < str_i.Count; y++) { //if (int_i_list.Contains(index_i)) // continue; //if (int_i_list.Count > 0) //{ // if (y < int_i_list[int_i_list.Count - 1]) // continue; //} if (Math.Abs(dd - xyz_i[y].Z) < 0.001) { index_i = y; break; } } for (int y = 0; y < str_t.Count; y++) { //if (int_t_list.Contains(index_t)) // continue; //if (int_t_list.Count > 0) //{ // if (y < int_t_list[int_t_list.Count - 1]) // continue; //} if (Math.Abs(dd - xyz_t[y].Z) < 0.001) { index_t = y; break; } } for (int y = 0; y < str_r.Count; y++) { //if (int_r_list.Contains(index_r)) // continue; //if (int_r_list.Count > 0) //{ // if (y < int_r_list[int_r_list.Count - 1]) // continue; //} if (Math.Abs(dd - xyz_r[y].Z) < 0.001) { index_r = y; break; } } //MessageBox.Show(index_i + "\n" + index_t + "\n" + index_r, "向日葵", MessageBoxButtons.OK); if (index_i != -1 && index_i != xyz_i.Count - 1) //当前检测点属于i列 { index_ii = index_i + 1; layername = str_i[index_i]; for (int y = 0; y < str_t.Count; y++) { if (int_t_list.Contains(y)) continue; if (int_t_list.Count > 0) { if (y < int_t_list[int_t_list.Count - 1]) continue; } if (str_t[y] == str_i[index_i]) { //看Z坐标是否符合要求,要求斜度不要太大 if ((xyz_i[index_i].Z - xyz_t[y].Z) / xyz_i[index_i].DistanceTo(xyz_t[y]) < 0.5) { index_t = y; //t列有 index_tt = y + 1; break; } } } if (index_t == -1) //t列没有 { if (int_t_list.Count == 0) index_t = 0; else index_t = int_t_list.Count - 1; index_tt = index_t; } for (int y = 0; y < str_r.Count; y++) { if (int_r_list.Contains(y)) continue; if (int_r_list.Count > 0) { if (y < int_r_list[int_r_list.Count - 1]) continue; } if (str_r[y] == str_i[index_i]) { //看Z坐标是否符合要求,要求斜度不要太大 if ((xyz_i[index_i].Z - xyz_r[y].Z) / xyz_i[index_i].DistanceTo(xyz_r[y]) < 0.5) { index_r = y; //r有 index_rr = y + 1; break; } } } if (index_r == -1) //r列没有 { if (int_r_list.Count == 0) index_r = 0; else index_r = int_r_list.Count - 1; index_rr = index_r; } } else if (index_t != -1 && index_t != xyz_t.Count - 1) //当前检测点属于t列 { index_tt = index_t + 1; layername = str_t[index_t]; for (int y = 0; y < str_i.Count; y++) { if (int_i_list.Contains(y)) continue; if (int_i_list.Count > 0) { if (y < int_i_list[int_i_list.Count - 1]) continue; } if (str_i[y] == str_t[index_t]) { //看Z坐标是否符合要求,要求斜度不要太大 if ((xyz_t[index_t].Z - xyz_i[y].Z) / xyz_t[index_t].DistanceTo(xyz_i[y]) < 0.5) { index_i = y; //i列有 index_ii = y + 1; break; } } } if (index_i == -1) //i列没有 { if (int_i_list.Count == 0) index_i = 0; else index_i = int_i_list.Count - 1; index_ii = index_i; } for (int y = 0; y < str_r.Count; y++) { if (int_r_list.Contains(y)) continue; if (int_r_list.Count > 0) { if (y < int_r_list[int_r_list.Count - 1]) continue; } if (str_r[y] == str_t[index_t]) { //看Z坐标是否符合要求,要求斜度不要太大 if ((xyz_t[index_t].Z - xyz_r[y].Z) / xyz_t[index_t].DistanceTo(xyz_r[y]) < 0.5) { index_r = y; //r有 index_rr = y + 1; break; } } } if (index_r == -1) //r列没有 { if (int_r_list.Count == 0) index_r = 0; else index_r = int_r_list.Count - 1; index_rr = index_r; } } else if (index_r != -1 && index_r != xyz_r.Count - 1) //当前检测点属于r列 { index_rr = index_r + 1; layername = str_r[index_r]; for (int y = 0; y < str_t.Count; y++) { if (int_t_list.Contains(y)) continue; if (int_t_list.Count > 0) { if (y < int_t_list[int_t_list.Count - 1]) continue; } if (str_t[y] == str_r[index_r]) { //看Z坐标是否符合要求,要求斜度不要太大 if ((xyz_r[index_r].Z - xyz_t[y].Z) / xyz_r[index_r].DistanceTo(xyz_t[y]) < 0.5) { index_t = y; //t列有 index_tt = y + 1; break; } } } if (index_t == -1) //t列没有 { if (int_t_list.Count == 0) index_t = 0; else index_t = int_t_list.Count - 1; index_tt = index_t; } for (int y = 0; y < str_i.Count; y++) { if (int_i_list.Contains(y)) continue; if (int_i_list.Count > 0) { if (y < int_i_list[int_i_list.Count - 1]) continue; } if (str_i[y] == str_r[index_r]) { //看Z坐标是否符合要求,要求斜度不要太大 if ((xyz_r[index_r].Z - xyz_i[y].Z) / xyz_r[index_r].DistanceTo(xyz_i[y]) < 0.5) { index_i = y; //i有 index_ii = y + 1; break; } } } if (index_i == -1) //i列没有 { if (int_i_list.Count == 0) index_i = 0; else index_i = int_i_list.Count - 1; index_ii = index_i; } } if (index_i == -1) { index_i = 0; index_ii = 0; } if (index_t == -1) { index_t = 0; index_tt = 0; } if (index_r == -1) { index_r = 0; index_rr = 0; } if (index_i >= xyz_i.Count - 1) { index_i = xyz_i.Count - 1; index_ii = xyz_i.Count - 1; } if (index_t >= xyz_t.Count - 1) { index_t = xyz_t.Count - 1; index_tt = xyz_t.Count - 1; } if (index_r >= xyz_r.Count - 1) { index_r = xyz_r.Count - 1; index_rr = xyz_r.Count - 1; } //MessageBox.Show(index_i + "\n" + index_t + "\n" + index_r, "向日葵", MessageBoxButtons.OK); try { XYZ delta = xyz_i[index_i]; XYZ p1a = xyz_i[index_i] - delta; XYZ p2a = xyz_t[index_t] - delta; XYZ p3a = xyz_r[index_r] - delta; XYZ p1b = xyz_i[index_ii] - delta; XYZ p2b = xyz_t[index_tt] - delta; XYZ p3b = xyz_r[index_rr] - 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) { solid_list.Add(solid); layername_list.Add(layername); kh1_list.Add(kh_list[i]); kh2_list.Add(kh_list[t]); kh3_list.Add(kh_list[r]); delta_list.Add(delta); int_list.Add(index_i); index1_list.Add(i); index2_list.Add(t); index3_list.Add(r); int_i_list.Add(index_i); int_t_list.Add(index_t); int_r_list.Add(index_r); } } catch { continue; } //} //} } } //材质集合 FilteredElementCollector m_collector = new FilteredElementCollector(doc); ElementClassFilter m_typefilter = new ElementClassFilter(typeof(Material)); IList mtset = m_collector.WherePasses(m_typefilter).ToElements(); IList mtnameset = new List(); foreach (Element e in mtset) { mtnameset.Add(e.Name); } //做材质 for (int i = 0; i < name_list.Count; i++) { string str = name_list[i]; if (mtnameset.Contains(str)) continue; Transaction transaction0 = new Transaction(doc, "yy"); FailureHandlingOptions failureHandlingOptions = transaction0.GetFailureHandlingOptions(); FailureHandler failureHandler = new FailureHandler(); failureHandlingOptions.SetFailuresPreprocessor(failureHandler); failureHandlingOptions.SetClearAfterRollback(true); transaction0.SetFailureHandlingOptions(failureHandlingOptions); transaction0.Start(); Material m = creatematerial(doc, str, false); 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; m.Color = new Color((byte)int_Red, (byte)int_Green, (byte)int_Blue); m.MaterialClass = "地质材质"; mtset.Add(m); transaction0.Commit(); } //新材质集合 FilteredElementCollector m_collector2 = new FilteredElementCollector(doc); ElementClassFilter m_typefilter2 = new ElementClassFilter(typeof(Material)); IList mtset2 = m_collector2.WherePasses(m_typefilter2).ToElements(); int t1 = solid_list.Count; string s1 = "{0} of " + t1.ToString(); string caption1 = "生成"; using (FilterProgressForm prf1 = new FilterProgressForm(caption1, s1, t1)) { //for (int i = 0; i <= 10; i++) for (int i = 0; i <= solid_list.Count - 1; i++) { //做族 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(); FamilyParameter fp = familydoc_gd.FamilyManager.AddParameter("材质", BuiltInParameterGroup.PG_MATERIALS, ParameterType.Material, true); Element e = FreeFormElement.Create(familydoc_gd, solid_list[i]); familydoc_gd.FamilyManager.AssociateElementParameterToFamilyParameter(e.LookupParameter("材质"), fp); transactionff.Commit(); string tmp_fName = tmppath; tmp_fName += "\\地质" + layername_list[i] + "层_" + index1_list[i] + "_" + index2_list[i] + "_" + index3_list[i] + "_"; tmp_fName += int_list[i].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_list[i], symbol, curview.GenLevel, StructuralType.NonStructural); transaction8.Commit(); Transaction transaction9 = new Transaction(doc, "yy"); transaction9.Start(); fi.LookupParameter("注释").Set(layername_list[i]); fi.LookupParameter("孔号1").Set(kh1_list[i]); fi.LookupParameter("孔号2").Set(kh2_list[i]); fi.LookupParameter("孔号3").Set(kh3_list[i]); foreach (Element me in mtset2) { if (me.Name == layername_list[i]) { fi.LookupParameter("材质").Set(me.Id); break; } } transaction9.Commit(); if (prf1.progressBar1.Tag.ToString() == "Cancel") break; prf1.Increment(); } } #endregion 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(); Transaction transaction100 = new Transaction(doc, "yy"); transaction100.Start(); doc.Delete(floor.Id); transaction100.Commit(); } excel.Quit(); excel = null; } status = transGroup.Assimilate(); foreach (string delpath in delfile_list) { System.IO.File.Delete(delpath); } return Result.Succeeded; } //求b点相对于a点的角度(从aX转到ab的角度),从0到360。 public double ang_of_vector(XYZ a, XYZ b) { Double angle = 0; if (a.X == b.X) { if (a.Y > b.Y) angle = 270; else angle = 90; } if (a.Y == b.Y) { if (a.X > b.X) angle = 180; else angle = 0; } if (a.X != b.X && a.Y != b.Y) { double atan = Math.Atan((b.Y - a.Y) / (b.X - a.X)) * 180 / Math.PI; if (b.X > a.X && b.Y > a.Y) angle = atan; if (b.X < a.X) angle = atan + 180; if (b.X > a.X && b.Y < a.Y) angle = atan + 360; } return angle; } //创建新材质 public Material creatematerial(Autodesk.Revit.DB.Document doc, string name, Boolean stru) { Material material = null; try { ElementId materialId = Material.Create(doc, name); material = doc.GetElement(materialId) as Material; StructuralAsset strucAsset = new StructuralAsset("创筑", StructuralAssetClass.Undefined); strucAsset.Behavior = StructuralBehavior.Isotropic; PropertySetElement propertySet = PropertySetElement.Create(doc, strucAsset); propertySet.get_Parameter(BuiltInParameter.PROPERTY_SET_NAME).Set(name); propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_CLASS).Set((int)StructuralMaterialType.Undefined); propertySet.get_Parameter(BuiltInParameter.PHY_MATERIAL_PARAM_UNIT_WEIGHT).Set(232); material.SetMaterialAspectByPropertySet(Autodesk.Revit.DB.MaterialAspect.Structural, propertySet.Id); } catch { } return material; } } [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class DWGDataExport : IExternalCommand { public Result Execute(Autodesk.Revit.UI.ExternalCommandData CommandData, ref string Message, ElementSet elementset) { 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 path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\data.csv"; //所有文字 List textnote_list = new List(); ICollection textnoteid_list = (new FilteredElementCollector(doc, curview.Id)). WherePasses(new ElementClassFilter(typeof(TextNote))).ToElementIds(); foreach (ElementId eid in textnoteid_list) textnote_list.Add(doc.GetElement(eid) as TextNote); //所有线条 List detailline_list = new List(); ICollection detaillineid_list = (new FilteredElementCollector(doc, curview.Id)). WherePasses(new CurveElementFilter(CurveElementType.DetailCurve)).ToElementIds(); foreach (ElementId eid in detaillineid_list) detailline_list.Add(doc.GetElement(eid) as DetailCurve); //所有1000的水平分格线 List dl_fg_list = new List(); foreach (DetailCurve dltmp in detailline_list) { if (dltmp.GetType().Name != "DetailLine") continue; DetailLine dl = dltmp as DetailLine; if (dltmp.GeometryCurve.Length < 900 / 304.8 || dltmp.GeometryCurve.Length > 1100 / 304.8) continue; XYZ pp1 = dl.GeometryCurve.GetEndPoint(0); XYZ pp2 = dl.GeometryCurve.GetEndPoint(1); if (Math.Abs(pp1.Y - pp2.Y) < 0.1) dl_fg_list.Add(dl); } XYZ origin = new XYZ(-2390 / 304.8, 9216 / 304.8, 0); XYZ origin2 = new XYZ(-2390 / 304.8, 9216 / 304.8, 0); try { origin = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击图框左上角……"); origin2 = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击第二个图框左上角……"); } catch { return Result.Succeeded; } string allstr = ""; //总记录 List maybe_error_list = new List(); //可能出错的行 double column1_x1 = 1000 / 304.8; //第2列地层编号左侧x坐标 double column1_x2 = 2000 / 304.8; //第2列地层编号右侧x坐标 double column3_x1 = 2000 / 304.8; //第3列层底高程左侧x坐标 double column3_x2 = 3000 / 304.8; //第3列层底高程右侧x坐标 double column_y = -8000 / 304.8; //此Y坐标以下为地层数据 TransactionStatus status = TransactionStatus.Uninitialized; TransactionGroup transGroup = new TransactionGroup(doc, "地质建模"); if (transGroup.Start() == TransactionStatus.Started) { List del_textnote_list = new List(); //被归并或被排除的textnote,后面被排除 foreach (TextNote tntmp in textnote_list) { if (tntmp.Text == "汤世志" || tntmp.Text == "编 录") del_textnote_list.Add(tntmp); } int k = 0; string test = ""; do //for (int k = 0; k <= 10; k++) //钻点数量 { //求第i格的数字,表示地层编号 try { XYZ origin_k = origin + new XYZ(k * 21000 / 304.8, 0, 0); List textnote_k_list = new List(); //当前图框里的textnote foreach (TextNote tntmp in textnote_list) { //图框尺寸 if (tntmp.Coord.X > origin_k.X && tntmp.Coord.X < origin_k.X + 18000 / 304.8 && tntmp.Coord.Y > origin_k.Y - 48700 / 304.8 && tntmp.Coord.Y < origin_k.Y) { //消重 Boolean dub = false; for (int i = 0; i <= textnote_k_list.Count - 1; i++) { TextNote tntmp1 = textnote_k_list[i]; if (tntmp.Coord.DistanceTo(tntmp1.Coord) < 10 / 304.8 && tntmp.Text == tntmp1.Text) { dub = true; break; } } if (dub == false) textnote_k_list.Add(tntmp); } } TextNote zkbh_tn = Textnote_At_Point(origin_k + new XYZ(2000 / 304.8, -3550 / 304.8, 0), textnote_k_list); //钻孔编号 TextNote kkbg_tn = Textnote_At_Point(origin_k + new XYZ(2600 / 304.8, -5400 / 304.8, 0), textnote_k_list); //孔口标高 TextNote x_tn = Textnote_At_Point(origin_k + new XYZ(5970 / 304.8, -4426 / 304.8, 0), textnote_k_list); //孔口X TextNote y_tn = Textnote_At_Point(origin_k + new XYZ(5970 / 304.8, -5413 / 304.8, 0), textnote_k_list); //孔口Y test = zkbh_tn.Text; //归并类似3-1的文字 foreach (TextNote tntmp1 in textnote_k_list) { if (tntmp1.Coord.X > origin_k.X + column1_x2) continue; if (del_textnote_list.Contains(tntmp1)) continue; foreach (TextNote tntmp2 in textnote_k_list) { if (del_textnote_list.Contains(tntmp2)) continue; if (tntmp2.Coord.X > origin_k.X + column1_x2) continue; if (tntmp1.Id == tntmp2.Id) continue; //三重过滤:X相近、Y相近、字高不一 if (Math.Abs(tntmp1.Coord.X - tntmp2.Coord.X) < 300 / 304.8 && Math.Abs(tntmp1.Coord.Y - tntmp2.Coord.Y) < 50 / 304.8 && Math.Abs(tntmp1.Height - tntmp2.Height) > 0.001) { Transaction transaction = new Transaction(doc, "yy"); transaction.Start(); if (tntmp1.Height > tntmp2.Height) { tntmp1.Text = "=\"" + tntmp1.Text + "-" + tntmp2.Text + "\""; del_textnote_list.Add(tntmp2); } else { tntmp2.Text = "=\"" + tntmp2.Text + "-" + tntmp1.Text + "\""; del_textnote_list.Add(tntmp1); } transaction.Commit(); } } } textnote_k_list = textnote_k_list.Except(del_textnote_list).ToList(); List dcbh_list = new List(); //地层编号 List dcbh_Y_list = new List(); //地层编号Y坐标 List dcgc_list = new List(); //地层高程(层底) List dcgc_Y_list = new List(); //地层高程(层底)Y坐标 string record1 = zkbh_tn.Text + "," + kkbg_tn.Text + ","; string record2 = zkbh_tn.Text + "," + kkbg_tn.Text + ","; for (int i = 0; i <= textnote_k_list.Count - 1; i++) { TextNote tntmp = textnote_k_list[i]; if (tntmp.Coord.Y > origin_k.Y + column_y) continue; if (tntmp.Coord.X > origin_k.X + column1_x1 && tntmp.Coord.X < origin_k.X + column1_x2) { dcbh_list.Add(tntmp); dcbh_Y_list.Add(tntmp.Coord.Y); } if (tntmp.Coord.X > origin_k.X + column3_x1 && tntmp.Coord.X < origin_k.X + column3_x2) { dcgc_list.Add(tntmp); dcgc_Y_list.Add(tntmp.Coord.Y); } } dcbh_Y_list.Sort(); dcbh_Y_list.Reverse(); //从高到低 dcgc_Y_list.Sort(); dcgc_Y_list.Reverse(); //从高到低 //MessageBox.Show(dcgc_list[0].Text + "\n" + dcgc_list[1].Text + "\n" + dcgc_list[2].Text + "\n" + dcgc_list[3].Text + "\n" + dcgc_list[4].Text + "\n" + dcgc_list[5].Text + "\n" + dcgc_list[6].Text + "\n" + dcgc_list[7].Text , "向日葵", MessageBoxButtons.OK); //MessageBox.Show(k + "\n" + zkbh_tn.Text + "\n" + dcbh_Y_list.Count + "\n" + dcgc_Y_list.Count, "向日葵", MessageBoxButtons.OK); for (int i = 0; i < dcbh_list.Count; i++) { string dcbh_i = ""; string dcmc_i = ""; foreach (TextNote tn in dcbh_list) { if (tn.Coord.Y == dcbh_Y_list[i]) dcbh_i = tn.Text; } foreach (TextNote tn in dcgc_list) { if (tn.Coord.Y == dcgc_Y_list[i]) dcmc_i = tn.Text; } record1 += dcbh_i + ","; record2 += dcmc_i + ","; } //补齐空格 for (int i = 1; i <= 16 - dcbh_list.Count; i++) { record1 += " ,"; record2 += " ,"; } record1 += x_tn.Text + "," + y_tn.Text; record2 += x_tn.Text + "," + y_tn.Text; allstr += record1 + "\r\n" + record2 + "\r\n"; k++; } catch { MessageBox.Show(k + "\n" + "fail" + "\n" + test, "向日葵", MessageBoxButtons.OK); break; } } while (k > 0); Transaction transaction10 = new Transaction(doc, "yy"); transaction10.Start(); foreach (TextNote tn in del_textnote_list) doc.Delete(tn.Id); transaction10.Commit(); File.WriteAllText(path, allstr, Encoding.Default); } status = transGroup.RollBack(); string tips = "已导出到" + path + "。数据请查对。"; foreach (int t in maybe_error_list) tips += t.ToString() + " , "; MessageBox.Show(tips, "向日葵", MessageBoxButtons.OK); return Result.Succeeded; } //求某点处的textnote,在textnote_list范围内 public TextNote Textnote_At_Point(XYZ p, List textnote_list) { TextNote tn = null; foreach (TextNote tntmp in textnote_list) { if (tntmp.Coord.DistanceTo(p) < 200 / 304.8) { tn = tntmp; } } return tn; } } 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; } } }