using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; namespace uBIM_EarthTools { class Common { /// /// 三角剖分 /// /// 钻孔列表 /// 排除过长三角形边边长 /// 钻孔编号索引 public static List Delaunay(List boreholeList, double tolerance) { List list = new List(); List xyzList = boreholeList.Select(x => new XYZ(x.ValueList[0].Point.X, x.ValueList[0].Point.Y, 0)).ToList(); TriangleNet.Mesh mesh = new TriangleNet.Mesh(); TriangleNet.Geometry.InputGeometry inputGeometry = new TriangleNet.Geometry.InputGeometry(boreholeList.Count); foreach (XYZ item in xyzList) { inputGeometry.AddPoint(item.X, item.Y); } mesh.Triangulate(inputGeometry); foreach (TriangleNet.Data.Triangle item in mesh.Triangles) { if (IsCollinear(item) || MaxEdge(item) > tolerance) continue; int[] index = new int[3]; index[0] = item.P0; index[1] = item.P1; index[2] = item.P2; list.Add(index); } return list; } /// /// 判断三角形三点是否接近共线 /// /// /// public static bool IsCollinear(TriangleNet.Data.Triangle triangle) { XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0); XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0); XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0); Line line1 = Line.CreateUnbound(p0, p1 - p0); Line line2 = Line.CreateUnbound(p1, p2 - p1); Line line3 = Line.CreateUnbound(p2, p0 - p2); double d1 = line1.Project(p2).Distance / p0.DistanceTo(p1); double d2 = line2.Project(p0).Distance / p1.DistanceTo(p2); double d3 = line3.Project(p1).Distance / p2.DistanceTo(p0); if (Math.Min(Math.Min(d1, d2), d3) < 0.02) return true; else return false; } /// /// 三角形最长边长度 /// /// /// public static double MaxEdge(TriangleNet.Data.Triangle triangle) { XYZ p0 = new XYZ(triangle.GetVertex(0).X, triangle.GetVertex(0).Y, 0); XYZ p1 = new XYZ(triangle.GetVertex(1).X, triangle.GetVertex(1).Y, 0); XYZ p2 = new XYZ(triangle.GetVertex(2).X, triangle.GetVertex(2).Y, 0); return Math.Max(Math.Max(p0.DistanceTo(p1), p1.DistanceTo(p2)), p0.DistanceTo(p2)); } public static int IsTypeEquals(List boreholeList) { List typeList = boreholeList.Select(x => x.CurrentType).ToList(); if (typeList[0].Equals(typeList[1]) && typeList[0].Equals(typeList[2])) return 1; else if (typeList[0].Equals(typeList[1]) && !typeList[0].Equals(typeList[2])) return 2; else if (typeList[0].Equals(typeList[2]) && !typeList[0].Equals(typeList[1])) return 3; else if (typeList[1].Equals(typeList[2]) && !typeList[0].Equals(typeList[2])) return 4; else return 0; } /// /// 点1在XY平面(忽略Z值)绕中心点逆时针旋转到点2的弧度[0,2Π] /// /// /// /// /// public static double AngleOfThreePoint(XYZ firstPoint, XYZ centerPoint, XYZ lastPoint) { XYZ vector1 = firstPoint - centerPoint; XYZ vector2 = lastPoint - centerPoint; double angle = Math.Atan2(vector2.Y, vector2.X) - Math.Atan2(vector1.Y, vector1.X); if (angle < 0) { return angle += Math.PI * 2; } else if (angle == 0) { return angle = Math.PI * 2; } else return angle; } public static double PointToLinePedal(XYZ lineFirstPoint, XYZ lineSecondPoint, XYZ point) { double A = lineSecondPoint.Y - lineFirstPoint.Y; double B= lineSecondPoint.X - lineFirstPoint.X; double C = lineSecondPoint.X * lineFirstPoint.Y - lineFirstPoint.X*lineSecondPoint.Y; return (A * point.X + B * point.Y + C) / Math.Sqrt(A * A + B * B); } public static double PointToLineDistance(XYZ lineFirstPoint, XYZ lineSecondPoint, XYZ point) { double A = lineSecondPoint.Y - lineFirstPoint.Y; double B = lineSecondPoint.X - lineFirstPoint.X; double C = lineSecondPoint.X * lineFirstPoint.Y - lineFirstPoint.X * lineSecondPoint.Y; return (A * point.X + B * point.Y + C) / Math.Sqrt(A * A + B * B); } /// /// 创建材质 /// /// Autodesk.Revit.DB.Document /// 材质名称 /// public static Material CreateMaterial(Document doc, string name) { Material material = null; ElementId materialId = Material.Create(doc, name); material = doc.GetElement(materialId) as Material; StructuralAsset strucAsset = new StructuralAsset("uBIM", 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); return material; } /// /// 创建材质 /// /// Autodesk.Revit.DB.Document /// 材质名称列表 /// public static IList CreateMaterialElements(Document doc, List materialNameList) { Transaction transaction = new Transaction(doc); IList mtset = new FilteredElementCollector(doc) .WherePasses(new ElementClassFilter(typeof(Material))).ToElements(); transaction.Start("Create Material"); foreach (string type in materialNameList) { if (mtset.Select(x => x.Name).ToList().Contains(type)) continue; else { Material material = CreateMaterial(doc, type); Random randomNumFirst = new Random((int)DateTime.Now.Ticks); System.Threading.Thread.Sleep(randomNumFirst.Next(50)); Random randomNumSencond = new Random((int)DateTime.Now.Ticks); int intRed = randomNumFirst.Next(256); int intGreen = randomNumSencond.Next(256); int intBlue = (intRed + intGreen > 400) ? 0 : 400 - intRed - intGreen; intBlue = (intBlue > 255) ? 255 : intBlue; material.Color = new Color((byte)intRed, (byte)intGreen, (byte)intBlue); material.MaterialClass = "地质材质"; mtset.Add(material); } } transaction.Commit(); return mtset; } /// /// Transaction设置 /// /// Transaction public static void SetTransaction(Transaction trans) { FailureHandlingOptions failureHandlingOptions = trans.GetFailureHandlingOptions(); FailureHandler failureHandler = new FailureHandler(); failureHandlingOptions.SetFailuresPreprocessor(failureHandler); failureHandlingOptions.SetClearAfterRollback(true); trans.SetFailureHandlingOptions(failureHandlingOptions); } /// /// 求某点处的textnote,在textnote_list范围内 /// /// 寻找点 /// TextNote列表 /// 误差范围,单位mm /// textnote public static TextNote Textnote_At_Point(XYZ p, List textnoteList, double tolerance) { TextNote tn = null; XYZ newXyz = new XYZ(p.X, p.Y, textnoteList[0].Coord.Z); foreach (TextNote tntmp in textnoteList) { if (Math.Round(tntmp.Coord.DistanceTo(newXyz), 5) < (tolerance / 304.8)) { tn = tntmp; } } return tn; } public static void Swap(ref T x, ref T y) { T temp = x; x = y; y = temp; } } }