682 lines
25 KiB
C#
682 lines
25 KiB
C#
using Autodesk.Revit.DB;
|
||
using Autodesk.Revit.DB.Architecture;
|
||
using Autodesk.Revit.DB.Structure;
|
||
|
||
namespace ShrlAlgoToolkit.RevitCore.Extensions;
|
||
|
||
public static class ElementExtensions
|
||
{
|
||
/// <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;
|
||
}
|
||
public static void MoveElement(this Element item, XYZ vector)
|
||
{
|
||
if (item.Pinned || !item.IsValidObject || item == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var doc = item.Document;
|
||
var levels = doc.OfClass<Level>().OfType<Level>().OrderBy(l => l.Elevation).ToList();
|
||
if (item is FamilyInstance instance)
|
||
{
|
||
var baseElev = instance.get_BoundingBox(null).Min.Z + vector.Z;
|
||
var topElev = instance.get_BoundingBox(null).Max.Z + vector.Z;
|
||
var baseLevel = GetClosetLevel(levels, baseElev);
|
||
var topLevel = GetClosetLevel(levels, topElev);
|
||
|
||
switch (instance.Symbol.Family.FamilyPlacementType)
|
||
{
|
||
//柱
|
||
case FamilyPlacementType.TwoLevelsBased:
|
||
{
|
||
instance.Location.Move(vector);
|
||
|
||
instance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(baseLevel.Id);
|
||
instance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(baseElev - baseLevel.Elevation);
|
||
|
||
instance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(topLevel.Id);
|
||
instance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(topElev - topLevel.Elevation);
|
||
}
|
||
break;
|
||
case FamilyPlacementType.ViewBased:
|
||
break;
|
||
case FamilyPlacementType.WorkPlaneBased:
|
||
{
|
||
//instance.Location.Move(vector);
|
||
var param = instance.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
|
||
if (param != null && !param.IsReadOnly)
|
||
{
|
||
ElementTransformUtils.MoveElement(doc, instance.Id, XYZ.BasisZ * vector.Z);
|
||
|
||
//var value = param.AsDouble() + vector.Z;
|
||
//param.Set(value);
|
||
}
|
||
|
||
doc.Regenerate();
|
||
|
||
if (instance.Host == null)
|
||
{
|
||
ElementTransformUtils.MoveElement(doc, instance.Id, vector.Flatten());
|
||
}
|
||
}
|
||
break;
|
||
case FamilyPlacementType.OneLevelBased:
|
||
{
|
||
ElementTransformUtils.MoveElement(doc, instance.Id, vector);
|
||
}
|
||
break;
|
||
case FamilyPlacementType.OneLevelBasedHosted:
|
||
{
|
||
var ins = doc.Create
|
||
.NewFamilyInstance(
|
||
instance.GetLocXYZ(),
|
||
instance.Symbol,
|
||
instance.Host,
|
||
baseLevel,
|
||
StructuralType.NonStructural);
|
||
ins.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM)
|
||
.Set(baseElev - baseLevel.Elevation);
|
||
doc.Delete(instance.Id);
|
||
}
|
||
break;
|
||
case FamilyPlacementType.CurveBased:
|
||
{
|
||
instance.Location.Move(vector);
|
||
//var loc = instance.GetLocCurve().CreateTransformed(Transform.CreateTranslation(vector)) as Line;
|
||
//doc.Create.NewFamilyInstance(instance.HostFace, loc, instance.Symbol);
|
||
//doc.Delete(instance.Id);
|
||
}
|
||
break;
|
||
case FamilyPlacementType.CurveBasedDetail:
|
||
break;
|
||
//梁
|
||
case FamilyPlacementType.CurveDrivenStructural:
|
||
{
|
||
//instance.Location.Move(vector);
|
||
var loc = instance.GetCurve().CreateTransformed(Autodesk.Revit.DB.Transform.CreateTranslation(vector));
|
||
//var newLoc =
|
||
doc.Create.NewFamilyInstance(loc, instance.Symbol, baseLevel, StructuralType.Beam);
|
||
doc.Delete(instance.Id);
|
||
|
||
//ElementTransformUtils.MoveElement(doc, instance.Id, vector.Flatten());
|
||
}
|
||
break;
|
||
case FamilyPlacementType.Adaptive:
|
||
break;
|
||
case FamilyPlacementType.Invalid:
|
||
break;
|
||
default:
|
||
break;
|
||
}
|
||
}
|
||
else if (item is Wall wall)
|
||
{
|
||
var flat = vector.Flatten();
|
||
ElementTransformUtils.MoveElement(doc, wall.Id, flat);
|
||
doc.Regenerate();
|
||
SetWallHeight(vector, levels, wall);
|
||
var elemIds = wall.FindInserts(true, true, true, true);
|
||
foreach (var id in elemIds)
|
||
{
|
||
var elem = doc.GetElement(id);
|
||
if (elem is Wall nestWall)
|
||
{
|
||
SetWallHeight(vector, levels, nestWall);
|
||
}
|
||
else
|
||
{
|
||
MoveElement(elem, vector);
|
||
}
|
||
}
|
||
//墙饰条
|
||
var sweeps = doc.OfClass
|
||
<WallSweep>().OfType<WallSweep>().Where(s => s.GetHostIds().Contains(wall.Id));
|
||
foreach (var sweep in sweeps)
|
||
{
|
||
//ElementTransformUtils.MoveElement(doc, sweep.Id, flat);
|
||
var boundingBox = sweep.get_BoundingBox(null);
|
||
var offset = boundingBox.Min.Z + vector.Z;
|
||
|
||
var baseLevel = levels.First(l => Math.Abs(l.Elevation - offset) == levels.Min(l => Math.Abs(l.Elevation - offset)));
|
||
sweep.get_Parameter(BuiltInParameter.WALL_SWEEP_LEVEL_PARAM).Set(baseLevel.Id);
|
||
sweep.get_Parameter(BuiltInParameter.WALL_SWEEP_OFFSET_PARAM).Set(offset - baseLevel.Elevation);
|
||
}
|
||
//依附在墙上的实例
|
||
var instances = doc.OfClass<FamilyInstance>().OfType<FamilyInstance>().Where(s =>
|
||
{
|
||
|
||
var stackedWallIds = wall.GetStackedWallMemberIds();
|
||
if (stackedWallIds.Count > 0)
|
||
{
|
||
return stackedWallIds.Any(id => s.Host?.Id == id);
|
||
}
|
||
return s.Host?.Id == wall.Id;
|
||
}).ToList();
|
||
foreach (var ins in instances)
|
||
{
|
||
//ins.Location.Move(vector);
|
||
ElementTransformUtils.MoveElement(doc, ins.Id, vector.Z * XYZ.BasisZ);
|
||
}
|
||
|
||
//ElementTransformUtils.CopyElements(v1, [wall.Id], v2, Transform.Identity, new CopyPasteOptions());
|
||
//var b = wall.Location.Move(vector);
|
||
|
||
//var loc = wall.GetLocCurve();
|
||
//var c = loc.CreateTransformed(Transform.CreateTranslation(vector));
|
||
//(wall.Location as LocationCurve).Curve = c; //可以移动,但是偏移量属性没更新
|
||
}
|
||
else if (item is Room room)
|
||
{
|
||
}
|
||
else if (item is Stairs stairs)
|
||
{
|
||
var flat = vector.Flatten();
|
||
ElementTransformUtils.MoveElement(doc, item.Id, flat);
|
||
}
|
||
else if (item is ModelCurve curve)//房间分割
|
||
{
|
||
|
||
}
|
||
else if (item is Railing railing)
|
||
{
|
||
if (railing.HasHost)
|
||
{
|
||
|
||
}
|
||
else//连带主体移动
|
||
{
|
||
ElementTransformUtils.MoveElement(doc, item.Id, vector);
|
||
}
|
||
}
|
||
//坡道
|
||
else if (item.Category.ToBuiltInCategory() == BuiltInCategory.OST_Ramps)
|
||
{
|
||
var flat = vector.Flatten();
|
||
ElementTransformUtils.MoveElement(doc, item.Id, flat);
|
||
}
|
||
else if (item is TopographySurface surface)
|
||
{
|
||
}
|
||
else if (item is SlabEdge or Fascia or Gutter)
|
||
{
|
||
return;
|
||
}
|
||
//else if (item is CeilingAndFloor ceilingAndFloor)
|
||
//{
|
||
// ElementTransformUtils.MoveElement(doc, ceilingAndFloor.Id, vector);
|
||
//}
|
||
else if (item is Opening opening)
|
||
{
|
||
if (opening.Host is Wall)
|
||
{
|
||
ElementTransformUtils.MoveElement(doc, opening.Id, vector.Z * XYZ.BasisZ);
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ElementTransformUtils.MoveElement(doc, item.Id, vector);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 设置墙高度
|
||
/// </summary>
|
||
/// <param name="vector"></param>
|
||
/// <param name="levels"></param>
|
||
/// <param name="wall"></param>
|
||
private static void SetWallHeight(XYZ vector, List<Level> levels, Wall wall)
|
||
{
|
||
var boundingBox = wall.get_BoundingBox(null);
|
||
//底部实际高度
|
||
var bottomElev = boundingBox.Min.Z + vector.Z;
|
||
var topElev = boundingBox.Max.Z + vector.Z;
|
||
//查找距离底部偏移最近的Level
|
||
var baseLevel = GetClosetLevel(levels, bottomElev);
|
||
wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(baseLevel.Id);
|
||
wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(bottomElev - baseLevel.Elevation);
|
||
//是否有顶部约束
|
||
var topContraint = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
|
||
if (topContraint != ElementId.InvalidElementId)
|
||
{
|
||
var topLevel = GetClosetLevel(levels, topElev);
|
||
|
||
wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(topLevel.Id);
|
||
wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(topElev - topLevel.Elevation);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 获取距离最近的标高
|
||
/// </summary>
|
||
/// <param name="levels"></param>
|
||
/// <param name="elev">高度</param>
|
||
/// <returns></returns>
|
||
private static Level GetClosetLevel(List<Level> levels, double elev)
|
||
{
|
||
return levels.First(l => Math.Abs(l.Elevation - elev) == levels.Min(l => Math.Abs(l.Elevation - elev)));
|
||
}
|
||
/// <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="element"></param>
|
||
/// <returns></returns>
|
||
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;
|
||
}
|
||
/// <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.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;
|
||
}
|
||
|
||
/// <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);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|