Files

280 lines
9.1 KiB
C#
Raw Permalink Normal View History

2025-04-24 20:56:44 +08:00
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
2026-02-21 16:31:24 +08:00
using ShrlAlgoToolkit.RevitCore.Assists;
2025-04-24 20:56:44 +08:00
2026-02-21 16:31:24 +08:00
namespace ShrlAlgoToolkit.RevitCore.Extensions;
2025-04-24 20:56:44 +08:00
/// <summary>
/// 房间类的扩展
/// </summary>
/// <remarks>
/// <para>房间的边界外圈是逆时针,所有内圈是顺时针,墙体相交会导致边界线被切分</para>
///<para>底部偏移 item.Room.BaseOffset = baseOffset;</para>
///<para>高度偏移 item.Room.LimitOffset = baseOffset;</para>
///<para>全部高度 item.Room.UnboundedHeight顶部-底部;</para>
/// </remarks>
public static class RoomExtensions
{
/// <summary>
/// 墙饰面
/// </summary>
/// <param name="room"></param>
/// <param name="height"></param>
/// <param name="newWallType"></param>
/// <returns>墙饰面与房间边界的字典</returns>
public static Dictionary<ElementId, ElementId> CreateWalls(this Room room, double height, WallType newWallType)
{
var doc = newWallType.Document;
var dictionary = new Dictionary<ElementId, ElementId>();
var levelId = room.LevelId;
var boundarySegments = room.GetBoundarySegments(
new SpatialElementBoundaryOptions { SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish }
);
if (boundarySegments == null)
{
return dictionary;
}
foreach (var list in boundarySegments)
{
if (list.Count == 0)
{
continue;
}
foreach (var boundarySegment in list)
{
var element = doc.GetElement(boundarySegment.ElementId);
if (element == null)
{
continue;
}
var category = doc.Settings.Categories.get_Item(BuiltInCategory.OST_RoomSeparationLines);
if (element.Category.Id == category.Id)
{
continue;
}
var wall = Wall.Create(doc, boundarySegment.GetCurve(), newWallType.Id, levelId, height, 0.0, false, false);
wall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM).Set(2);
dictionary.Add(wall.Id, boundarySegment.ElementId);
}
}
return dictionary;
}
/// <summary>
/// 创建房间的内建模型
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static DirectShape CreateSolid(this Room room)
{
return RoomSolid(room, room.GetBoundaryCurveLoops());
}
/// <summary>
/// 得到房间边界的线串
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static List<CurveLoop> GetBoundaryCurveLoops(this Room room)
{
var boundary = room.GetBoundarySegments(Options());
var list = new List<CurveLoop>();
if (boundary.Count != 0)
{
foreach (var list2 in boundary)
{
var curveLoop = new CurveLoop();
foreach (var boundarySegment in list2)
{
curveLoop.Append(boundarySegment.GetCurve());
}
list.Add(curveLoop);
}
}
return list;
}
/// <summary>
/// 房间边界组成的元素集合
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static List<Element> GetBoundaryElementList(this SpatialElement room)
{
if (room is null)
{
throw new ArgumentNullException(nameof(room));
}
var results = new List<Element>();
var segments = room.GetBoundarySegments(Options()).SelectMany(s => s);
foreach (var segment in segments)
{
if (segment.ElementId == ElementId.InvalidElementId)
{
continue;
}
if (results.FirstOrDefault(f => f.Id == segment.ElementId) != null)
{
continue;
}
var elm = room.Document.GetElement(segment.ElementId);
results.Add(elm);
}
return results;
}
/// <summary>
/// 房间边界的对应字典(元素-曲线)集合
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static Dictionary<Element, Curve> GetElementCurveDict(this Room room)
{
if (room is null)
{
throw new ArgumentNullException(nameof(room));
}
var doc = room.Document;
if (doc is null)
{
throw new ArgumentNullException(nameof(doc));
}
var segments = room.GetBoundarySegments(Options()).SelectMany(s => s);
return segments.ToDictionary(k => doc.GetElement(k.ElementId), v => v.GetCurve());
}
/// <summary>
/// 获取房间几何体相交的元素
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static FilteredElementCollector GetIntersectElements(this Room room)
{
var doc = room.Document;
var solid = new SpatialElementGeometryCalculator(doc).CalculateSpatialElementGeometry(room).GetGeometry();
ElementIntersectsSolidFilter filter = new(solid);
return new FilteredElementCollector(doc).WherePasses(filter);
}
/// <summary>
/// 获取房间最外侧边界
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static CurveArray GetOuterBoundary(this Room room)
{
var allCurves = new CurveArray();
var boundarySegments = room.GetBoundarySegments(Options()).First();
foreach (var bs in boundarySegments)
{
allCurves.Append(bs.GetCurve());
}
return allCurves;
}
private static SpatialElementBoundaryOptions Options()
{
return new SpatialElementBoundaryOptions { SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish };
}
/// <summary>
/// 获取房间的几何体
/// </summary>
/// <param name="room"></param>
/// <returns></returns>
public static Solid GetSolid(this Room room)
{
var doc = room.Document;
var segc = new SpatialElementGeometryCalculator(doc);
var segr = segc.CalculateSpatialElementGeometry(room);
return segr.GetGeometry();
}
/// <summary>
2025-07-11 09:20:23 +08:00
/// 得到房间的三维实体
2025-04-24 20:56:44 +08:00
/// </summary>
/// <param name="room"></param>
/// <param name="curveLoops"></param>
/// <param name="material"></param>
/// <returns></returns>
private static DirectShape RoomSolid(Room room, List<CurveLoop> curveLoops, Material material = null)
{
var doc = room.Document;
var height = room.get_Parameter(BuiltInParameter.ROOM_HEIGHT).AsDouble();
var options =
material == null
? new SolidOptions(ElementId.InvalidElementId, ElementId.InvalidElementId)
: new SolidOptions(material.Id, ElementId.InvalidElementId);
2025-12-28 11:47:54 +08:00
var solid = GeometryCreationUtilities.CreateExtrusionGeometry(curveLoops, XYZ.BasisZ, height, options);
2025-04-24 20:56:44 +08:00
2025-07-11 09:20:23 +08:00
var directShape = doc.CreateDirectShapeInstance(
"房间实体",
BuiltInCategory.OST_GenericModel,
2025-12-28 11:47:54 +08:00
[solid]);
2025-07-11 09:20:23 +08:00
directShape.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(room.Name);
//ds.SetName(room.Name);
//var option = ds.GetOptions();
//option.ReferencingOption = DirectShapeReferencingOption.NotReferenceable;
//ds.SetOptions(option);
//ds.AppendShape(new List<GeometryObject> { solid });
//room.Document.Regenerate();
2025-04-24 20:56:44 +08:00
var elements = new FilteredElementCollector(doc);
var solidFillPattern = elements.OfClass(typeof(FillPatternElement)).Cast<FillPatternElement>().First(a => a.GetFillPattern().IsSolidFill);
2025-12-28 11:47:54 +08:00
var color = ColorAssist.GetDistinctColorById(directShape.Id);
2025-04-24 20:56:44 +08:00
var ogs = new OverrideGraphicSettings();
ogs.SetProjectionLineColor(color);
#if REVIT2018
ogs.SetSurfaceTransparency(50);
ogs.SetProjectionFillColor(color);
ogs.SetProjectionFillPatternId(solidFillPattern.Id);
ogs.SetCutFillColor(color);
ogs.SetCutFillPatternId(solidFillPattern.Id);
2025-12-23 21:35:54 +08:00
doc.ActiveView.SetElementOverrides(directShape.Id, ogs);
2025-04-24 20:56:44 +08:00
#else
ogs.SetSurfaceBackgroundPatternColor(color);
ogs.SetSurfaceForegroundPatternId(solidFillPattern.Id);
ogs.SetSurfaceForegroundPatternColor(color);
ogs.SetCutBackgroundPatternColor(color);
ogs.SetCutForegroundPatternColor(color);
ogs.SetCutForegroundPatternId(solidFillPattern.Id);
ogs.SetSurfaceTransparency(50);
2025-12-23 21:35:54 +08:00
doc.ActiveView.SetElementOverrides(directShape.Id, ogs);
2025-04-24 20:56:44 +08:00
#endif
//foreach (Face face in solid.Faces)
//{
// room.Document.Paint(ds.Id,,);
// //PlanarFace pf = face as PlanarFace;
// //if (pf.FaceNormal.IsAlmostEqualTo(XYZ.BasisZ))
// //{
// // array.Append(face);
// // break;
// //}
//}
2025-12-23 21:35:54 +08:00
return directShape;
2025-04-24 20:56:44 +08:00
}
}