Files
Shrlalgo.RvKits/Sai.Toolkit.Revit/Assist/ElementAssist.cs

435 lines
15 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
using Autodesk.Revit.DB;
namespace Sai.Toolkit.Revit.Assist;
public static class ElementAssist
{
/// <summary>
/// 镜像元素
/// </summary>
/// <param name="element"></param>
/// <param name="plane"></param>
/// <returns></returns>
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);
/// <summary>
/// 移动元素
/// </summary>
/// <param name="element"></param>
/// <param name="deltaX"></param>
/// <param name="deltaY"></param>
/// <param name="deltaZ"></param>
/// <returns></returns>
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;
}
/// <summary>
/// 移动元素
/// </summary>
/// <param name="element"></param>
/// <param name="vector"></param>
/// <returns></returns>
public static Element Move(this Element element, XYZ vector)
{
ElementTransformUtils.MoveElement(element.Document, element.Id, vector);
return element;
}
/// <summary>
/// 旋转元素
/// </summary>
/// <param name="element"></param>
/// <param name="axis"></param>
/// <param name="angle"></param>
/// <returns></returns>
public static Element Rotate(this Element element, Line axis, double angle)
{
ElementTransformUtils.RotateElement(element.Document, element.Id, axis, angle);
return element;
}
/// <summary>
/// 能否镜像
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public static bool CanBeMirrored(this Element element)
{
return ElementTransformUtils.CanMirrorElement(element.Document, element.Id);
}
/// <summary>
/// 获取标高
/// </summary>
2025-02-10 20:53:40 +08:00
/// <param name="element"></param>
2024-09-22 11:05:41 +08:00
/// <returns></returns>
2025-02-10 20:53:40 +08:00
public static ElementId GetLevelId(this Element element)
2024-09-22 11:05:41 +08:00
{
// 定义需要检查的参数列表
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)
{
2025-02-10 20:53:40 +08:00
var baseLevelId = element.get_Parameter(param)?.AsElementId();
2024-09-22 11:05:41 +08:00
if (baseLevelId != ElementId.InvalidElementId && baseLevelId != null)
{
return baseLevelId;
}
}
//最后检查楼板或族基准标高
2025-02-10 20:53:40 +08:00
return element.LevelId;
2024-09-22 11:05:41 +08:00
}
/// <summary>
/// 转换类型
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="element"></param>
/// <returns></returns>
public static T Cast<T>(this Element element) where T : Element
{
return (T)element;
}
/// <summary>
/// 合并几何
/// </summary>
/// <param name="firstElement"></param>
/// <param name="secondElement"></param>
public static void JoinGeometry(this Element firstElement, Element secondElement)
{
JoinGeometryUtils.JoinGeometry(firstElement.Document, firstElement, secondElement);
}
/// <summary>
/// 分离几何
/// </summary>
/// <param name="firstElement"></param>
/// <param name="secondElement"></param>
public static void UnJoinGeometry(this Element firstElement, Element secondElement)
{
JoinGeometryUtils.UnjoinGeometry(firstElement.Document, firstElement, secondElement);
}
/// <summary>
/// 是否连接
/// </summary>
/// <param name="firstElement"></param>
/// <param name="secondElement"></param>
/// <returns></returns>
public static bool AreElementsJoined(this Element firstElement, Element secondElement)
{
return JoinGeometryUtils.AreElementsJoined(firstElement.Document, firstElement, secondElement);
}
/// <summary>
/// 切换连接顺序
/// </summary>
/// <param name="firstElement"></param>
/// <param name="secondElement"></param>
public static void SwitchJoinOrder(this Element firstElement, Element secondElement)
{
JoinGeometryUtils.SwitchJoinOrder(firstElement.Document, firstElement, secondElement);
}
/// <summary>
/// 确定两个连接元素中的第一个是否正在切割第二个元素
/// </summary>
/// <param name="firstElement"></param>
/// <param name="secondElement"></param>
/// <returns></returns>
public static bool IsCuttingElementInJoin(this Element firstElement, Element secondElement)
{
return JoinGeometryUtils.IsCuttingElementInJoin(firstElement.Document, firstElement, secondElement);
}
/// <summary>
/// 获取连接的元素
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
public static ICollection<ElementId> 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;
}
/// <summary>
/// 获取参数值
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
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
}
}
/// <summary>
/// 优先获取实例参数,若无则获取类型参数
/// </summary>
/// <param name="element"></param>
/// <param name="parameterName"></param>
/// <returns></returns>
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.Document?.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;
}
/// <summary>
/// 管理图元在各个视图的可见性
/// </summary>
/// <param name="form"></param>
/// <param name="visibility"></param>
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);
}
/// <summary>
/// 线性阵列
/// </summary>
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<Face> faces, out List<Edge> edges)
{
//实例族的GeometryElement集合中具有Solid等几何对象的原因是由于族实例对象碰撞后软件自动会使用geometryInstance用来指定其位置即使碰撞后移开用Solid作为其几何体
//GeometryInstance Transform是族实例在全局坐标系的变换
faces = [];
edges = [];
//var references = new List<Reference>();
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<Edge>());
}
if (solid.Faces.Size > 0)
{
faces.AddRange(solid.Faces.OfType<Face>());
}
}
}
}
}
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);
}
}
}
}
/// <summary>
/// 修改元素面颜色(待测试)
/// </summary>
/// <param name="element"></param>
/// <param name="materialName"></param>
/// <param name="color"></param>
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);
}
}
}
}
}
}
}