using System; using System.IO; using System.Linq; using System.Text; using System.Windows.Forms; using System.Collections.Generic; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using Autodesk.Revit.UI.Selection; namespace EarthLayerModel { [Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Manual)] public class uBIM_EarthTools : 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"; //MessageBox.Show("注意要在±0平面视图运行。", "向日葵", MessageBoxButtons.OK); //所有文字 List textnoteList = new List(); ICollection textnoteid_list = (new FilteredElementCollector(doc, curview.Id)). WherePasses(new ElementClassFilter(typeof(TextNote))).ToElementIds(); foreach (ElementId eid in textnoteid_list) textnoteList.Add(doc.GetElement(eid) as TextNote); //所有线条 //List detaillineList = new List(); //ICollection detaillineidList = (new FilteredElementCollector(doc, curview.Id)). // WherePasses(new CurveElementFilter(CurveElementType.DetailCurve)).ToElementIds(); //foreach (ElementId eid in detaillineidList) // detaillineList.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(); XYZ origin2 = new XYZ(); try { origin = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击图框左上角……"); origin2 = uidoc.Selection.PickPoint(ObjectSnapTypes.Endpoints, "点击第二个图框左上角……"); } catch { return Result.Cancelled; } string allstr = ""; //总记录 List maybe_error_list = new List(); //可能出错的行 //——————————————以下为深国际商业及写字楼的dwg定位数据—————————————— //double column1_x1 = 2390 / 304.8; //第一列地层编号左侧x坐标 //double column1_x2 = 3390 / 304.8; //第一列地层编号右侧x坐标 //double column3_x1 = 4390 / 304.8; //第三列层底高程左侧x坐标 //double column3_x2 = 5390 / 304.8; //第三列层底高程右侧x坐标 //double column_y = -9000 / 304.8; //此Y坐标以下为地层数据 //——————————————以下为dwg定位数据—————————————— double column1_x1 = 43.2 / 304.8; //地层编号左侧x坐标 double column1_x2 = 52.9896 / 304.8; //地层编号右侧x坐标 double column3_x1 = 13.8312 / 304.8; //层底高程左侧x坐标 double column3_x2 = 23.6208 / 304.8; //层底高程右侧x坐标 double column_y = -62.3 / 304.8; //此Y坐标以下为地层数据 TransactionStatus status = TransactionStatus.Uninitialized; TransactionGroup transGroup = new TransactionGroup(doc, "地质建模"); if (transGroup.Start() == TransactionStatus.Started) { List del_textnote_list = new List(); //被归并的textnote,后面被排除 //int k = 0; //do for (int k = 0; k <= 7; k++) //钻点数量 { //求第i格的数字,表示地层编号 //try //{ XYZ origin_k = origin + new XYZ(k * (origin2.X - origin.X), 0, 0); List textnote_k_list = new List(); //当前图框里的textnote foreach (TextNote tntmp in textnoteList) { //tntmp.Coord.Y > origin_k.Y - 29106 / 304.8 && tntmp.Coord.Y < origin_k.Y) if (tntmp.Coord.X > origin_k.X && tntmp.Coord.X < origin_k.X + 178 / 304.8 && tntmp.Coord.Y > origin_k.Y - 267 / 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); } } if (textnote_k_list.Count == 0) //结束 break; //——————————————以下为深国际商业及写字楼的dwg定位数据—————————————— //TextNote zkbh_tn = Textnote_At_Point(origin_k + new XYZ(12890 / 304.8, -4350 / 304.8, 0), textnote_k_list); //钻孔编号 //TextNote kkbg_tn = Textnote_At_Point(origin_k + new XYZ(5200 / 304.8, -5220 / 304.8, 0), textnote_k_list); //孔口标高 //TextNote x_tn = Textnote_At_Point(origin_k + new XYZ(8490 / 304.8, -5220 / 304.8, 0), textnote_k_list); //孔口X //TextNote y_tn = Textnote_At_Point(origin_k + new XYZ(8490 / 304.8, -6100 / 304.8, 0), textnote_k_list); //孔口Y //——————————————以下为深国际住宅旋挖桩的dwg定位数据—————————————— TextNote zkbh_tn = Textnote_At_Point(origin_k + new XYZ(24.73 / 304.8, -21.46 / 304.8, 0), textnote_k_list); //钻孔编号 TextNote kkbg_tn = Textnote_At_Point(origin_k + new XYZ(24.73 / 304.8, -30.4 / 304.8, 0), textnote_k_list); //孔口标高 TextNote x_tn = Textnote_At_Point(origin_k + new XYZ(61.75 / 304.8, -21.46 / 304.8, 0), textnote_k_list); //孔口X TextNote y_tn = Textnote_At_Point(origin_k + new XYZ(61.75 / 304.8, -30.4 / 304.8, 0), textnote_k_list); //孔口Y if (zkbh_tn == null || kkbg_tn == null) //钻孔编号跟孔口标高不对应 continue; //归并类似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) < 6 / 304.8 && Math.Abs(tntmp1.Coord.Y - tntmp2.Coord.Y) < 4 / 304.8 && Math.Abs(tntmp1.Height - tntmp2.Height) > 0.00001 / 304.8) { //TaskDialog.Show("Show", (Math.Abs(tntmp1.Coord.X - tntmp2.Coord.X) * 304.8).ToString()); 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 dcmc_list = new List(); //地层名称 List dcmc_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) { dcmc_list.Add(tntmp); dcmc_Y_list.Add(tntmp.Coord.Y); } } dcbh_Y_list.Sort(); dcbh_Y_list.Reverse(); //从高到低 dcmc_Y_list.Sort(); dcmc_Y_list.Reverse(); //从高到低 for (int i = 0; i < dcbh_list.Count; i++) { if (i > dcmc_list.Count - 1) break; 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 dcmc_list) { if (tn.Coord.Y == dcmc_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" + "OK", "向日葵", 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(new XYZ(p.X, p.Y, tntmp.Coord.Z)) < 5 / 304.8) { tn = tntmp; } } return tn; } } }