Files
Shrlalgo.RvKits/Sai.Toolkit.Revit/Assist/ElementAssist.cs
2024-09-22 11:05:41 +08:00

435 lines
15 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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>
/// <param name="model"></param>
/// <returns></returns>
public static ElementId GetLevelId(this Element model)
{
// 定义需要检查的参数列表
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 = model.get_Parameter(param)?.AsElementId();
if (baseLevelId != ElementId.InvalidElementId && baseLevelId != null)
{
return baseLevelId;
}
}
//最后检查楼板或族基准标高
return model.LevelId;
}
/// <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);
}
}
}
}
}
}
}