using Autodesk.Revit.DB; using OfficeOpenXml.FormulaParsing.Excel.Functions.Logical; namespace ShrlAlgoToolkit.Revit.Assists; public static class ElementAssist { /// ///获取元素的包围框 /// /// /// public static BoundingBoxXYZ GetBoundingBox(List elements) { if (elements == null || elements.Count == 0) { return new BoundingBoxXYZ(); } var gmax = XYZ.Zero; var gmin = XYZ.Zero; var elementIds = elements.Select(e => e.Id).ToList(); var doc = elements.FirstOrDefault()?.Document; using (SubTransaction sub = new SubTransaction(doc)) { sub.Start(); Group g; if (doc.IsFamilyDocument) { g = doc.FamilyCreate.NewGroup(elementIds); } else { g = doc.Create.NewGroup(elementIds); } gmax = g.get_BoundingBox(null).Max; gmin = g.get_BoundingBox(null).Min; sub.RollBack(); } return new BoundingBoxXYZ { Max = gmax, Min = gmin }; } /// /// 镜像元素 /// /// /// /// public static Element Mirror(this Element element, Plane plane) { ElementTransformUtils.MirrorElement(element.Document, element.Id, plane); return element; } public static bool IsVisible(this Element elem, View view) => FilteredElementCollector.IsViewValidForElementIteration(elem.Document, view.Id) && new FilteredElementCollector(elem.Document, view.Id).ToElementIds().Any(id => id == elem.Id); /// /// 移动元素 /// /// /// /// /// /// public static Element Move(this Element element, double deltaX, double deltaY, double deltaZ) { ElementTransformUtils.MoveElement(element.Document, element.Id, new XYZ(deltaX, deltaY, deltaZ)); return element; } /// /// 移动元素 /// /// /// /// public static Element Move(this Element element, XYZ vector) { ElementTransformUtils.MoveElement(element.Document, element.Id, vector); return element; } /// /// 旋转元素 /// /// /// /// /// public static Element Rotate(this Element element, Line axis, double angle) { ElementTransformUtils.RotateElement(element.Document, element.Id, axis, angle); return element; } /// /// 能否镜像 /// /// /// public static bool CanBeMirrored(this Element element) { return ElementTransformUtils.CanMirrorElement(element.Document, element.Id); } /// /// 获取标高 /// /// /// public static ElementId GetLevelId(this Element element) { // 定义需要检查的参数列表 var parametersToCheck = new BuiltInParameter[] { BuiltInParameter.WALL_BASE_CONSTRAINT, // 墙 BuiltInParameter.SCHEDULE_BASE_LEVEL_PARAM, // 柱子标高 BuiltInParameter.INSTANCE_REFERENCE_LEVEL_PARAM, // 梁标高 BuiltInParameter.STAIRS_BASE_LEVEL_PARAM, // 楼梯标高 BuiltInParameter.INSTANCE_ELEVATION_PARAM, // 族实例明细表标高 BuiltInParameter.ROOF_CONSTRAINT_LEVEL_PARAM,//屋顶 BuiltInParameter.INSTANCE_SCHEDULE_ONLY_LEVEL_PARAM,// 族实例明细表标高 BuiltInParameter.RBS_START_LEVEL_PARAM// 管线标高 }; // 依次检查每个参数 foreach (var param in parametersToCheck) { var baseLevelId = element.get_Parameter(param)?.AsElementId(); if (baseLevelId != ElementId.InvalidElementId && baseLevelId != null) { return baseLevelId; } } //最后检查楼板或族基准标高 return element.LevelId; } /// /// 转换类型 /// /// /// /// public static T Cast(this Element element) where T : Element { return (T)element; } /// /// 合并几何 /// /// /// public static void JoinGeometry(this Element firstElement, Element secondElement) { JoinGeometryUtils.JoinGeometry(firstElement.Document, firstElement, secondElement); } /// /// 分离几何 /// /// /// public static void UnJoinGeometry(this Element firstElement, Element secondElement) { JoinGeometryUtils.UnjoinGeometry(firstElement.Document, firstElement, secondElement); } /// /// 是否连接 /// /// /// /// public static bool AreElementsJoined(this Element firstElement, Element secondElement) { return JoinGeometryUtils.AreElementsJoined(firstElement.Document, firstElement, secondElement); } /// /// 切换连接顺序 /// /// /// public static void SwitchJoinOrder(this Element firstElement, Element secondElement) { JoinGeometryUtils.SwitchJoinOrder(firstElement.Document, firstElement, secondElement); } /// /// 确定两个连接元素中的第一个是否正在切割第二个元素 /// /// /// /// public static bool IsCuttingElementInJoin(this Element firstElement, Element secondElement) { return JoinGeometryUtils.IsCuttingElementInJoin(firstElement.Document, firstElement, secondElement); } /// /// 获取连接的元素 /// /// /// public static ICollection GetJoinedElements(this Element element) { return JoinGeometryUtils.GetJoinedElements(element.Document, element); } public static bool SetValue(this Parameter parameter, object value) { var result = false; if (parameter.IsReadOnly) return false; switch (parameter.StorageType) { case StorageType.Integer: if (value is int i) { result = parameter.Set(i); } break; case StorageType.Double: if (value is double d) { result = parameter.Set(d); } break; case StorageType.String: if (value is string str) { result = parameter.Set(str); } break; case StorageType.ElementId: if (value is ElementId id) { result = parameter.Set(id); } break; case StorageType.None: break; default: throw new ArgumentOutOfRangeException(); } return result; } /// /// 获取参数值 /// /// /// public static object GetValue(this Parameter parameter) { object result = null; if (parameter == null) { throw new ArgumentNullException(nameof(parameter)); } switch (parameter.StorageType) { case StorageType.None: break; case StorageType.Integer: result = parameter.AsInteger(); break; case StorageType.Double: result = parameter.AsDouble(); break; case StorageType.String: //Revit数据库存储的值 var str = parameter.AsString(); if (string.IsNullOrEmpty(str)) { //用户可见的前端显示,如根据单位设置而显示的值 result = parameter.AsValueString(); } else { result = str; } break; case StorageType.ElementId: result = parameter.AsElementId(); break; } return result; } public static void SetElementTransparency(this Element element, int transparency) { try { var document = element.Document; var elementOverrides = document.ActiveView.GetElementOverrides(element.Id); elementOverrides.SetSurfaceTransparency(transparency); document.ActiveView.SetElementOverrides(element.Id, elementOverrides); } catch (Exception) { // ignored } } /// /// 优先获取实例参数,若无则获取类型参数 /// /// /// /// public static Parameter GetParameter(this Element element, string parameterName) { if (!element.IsValidObject) { throw new ArgumentNullException(nameof(element)); } //var parameterName = elem.LookupParameter(paramName); //if (parameterName == null) //{ // ElementId typeId = elem.GetTypeId(); // if (typeId != ElementId.InvalidElementId) // { // var elementFunc = elem.doc?.GetElement(typeId); // parameterName = elementFunc?.LookupParameter(paramName); // } //} var instanceParameter = element.LookupParameter(parameterName); if (instanceParameter is { HasValue: true }) { return instanceParameter; } var elementTypeId = element.GetTypeId(); if (elementTypeId == ElementId.InvalidElementId) { return instanceParameter; } var elementType = element.Document.GetElement(elementTypeId); var symbolParameter = elementType.LookupParameter(parameterName); return symbolParameter ?? instanceParameter; } /// /// 管理图元在各个视图的可见性 /// /// /// public static void AccessFamilyElementVisibility(this GenericForm form, FamilyElementVisibility visibility) { // 得到管理拉伸体的可见性的实例,并读取详细程度的设置 //FamilyElementVisibility visibility = form.GetVisibility(); //FamilyElementVisibilityType visibilityType = visibility.VisibilityType; //bool shownInCoarse = visibility.IsShownInCoarse; //bool shownInMedium = visibility.IsShownInMedium; //bool shownInFine = visibility.IsShownInFine; //// 设置为在各种详细程度中都显示拉伸体 //visibility.IsShownInTopBottom = false; //visibility.IsShownInCoarse = true; //visibility.IsShownInMedium = true; //visibility.IsShownInFine = true; // 注意:必须把可见性的修改设置回拉伸体 form.SetVisibility(visibility); } /// /// 线性阵列 /// public static void CreateLinearArray(this Element element, XYZ vector, int count, ArrayAnchorMember arrayAnchorMember) { var document = element.Document; LinearArray.Create(document, document.ActiveView, element.Id, count, vector, arrayAnchorMember); } public static void GetGeometryObj(this Element element, out List faces, out List edges) { //实例族的GeometryElement集合中具有Solid等几何对象的原因是由于族实例对象碰撞后,软件自动会使用geometryInstance用来指定其位置(即使碰撞后,移开),用Solid作为其几何体 //GeometryInstance Transform是族实例在全局坐标系的变换 faces = []; edges = []; //var references = new List(); Options geomOptions = new() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Medium, IncludeNonVisibleObjects = true }; var geoElem = element.get_Geometry(geomOptions); foreach (var obj in geoElem) { if (obj is GeometryInstance instance) { if (instance.GetSymbolGeometry().Any()) { foreach (var item in instance.GetSymbolGeometry()) { if (item is Solid solid) { if (solid.Edges.Size > 0) { edges.AddRange(solid.Edges.OfType()); } if (solid.Faces.Size > 0) { faces.AddRange(solid.Faces.OfType()); } } } } } else { if (obj is not Solid solid) { continue; } if (solid.Edges.Size > 0) { edges.AddRange(from Edge edge in solid.Edges select edge); } if (solid.Faces.Size > 0) { faces.AddRange(from Face face in solid.Faces select face); } } } } /// /// 修改元素面颜色(待测试) /// /// /// /// public static void ModifyElementFaceDisplay(this Element element, string materialName, Color color) { var doc = element.Document; var material = doc.GetElement(Material.Create(doc, materialName)) as Material; material!.Color = color; Options options = new() { ComputeReferences = true, DetailLevel = ViewDetailLevel.Medium }; var e = element.get_Geometry(options); foreach (var geometryObject in e) { var geoInstance = geometryObject as GeometryInstance; if (geoInstance != null) { var geoElement = geoInstance.GetInstanceGeometry(); foreach (var obj2 in geoElement) { var solid = obj2 as Solid; if (solid.SurfaceArea != 0) { foreach (Face face in solid.Faces) { doc.Paint(element.Id, face, material.Id); } } } } } } }