using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; using ShrlAlgoToolkit.RevitCore.Assists; namespace ShrlAlgoToolkit.RevitCore.Extensions; /// /// 房间类的扩展 /// /// /// 房间的边界外圈是逆时针,所有内圈是顺时针,墙体相交会导致边界线被切分 ///底部偏移 item.Room.BaseOffset = baseOffset; ///高度偏移 item.Room.LimitOffset = baseOffset; ///全部高度 item.Room.UnboundedHeight,顶部-底部; /// public static class RoomExtensions { /// /// 墙饰面 /// /// /// /// /// 墙饰面与房间边界的字典 public static Dictionary CreateWalls(this Room room, double height, WallType newWallType) { var doc = newWallType.Document; var dictionary = new Dictionary(); 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; } /// /// 创建房间的内建模型 /// /// /// public static DirectShape CreateSolid(this Room room) { return RoomSolid(room, room.GetBoundaryCurveLoops()); } /// /// 得到房间边界的线串 /// /// /// public static List GetBoundaryCurveLoops(this Room room) { var boundary = room.GetBoundarySegments(Options()); var list = new List(); 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; } /// /// 房间边界组成的元素集合 /// /// /// public static List GetBoundaryElementList(this SpatialElement room) { if (room is null) { throw new ArgumentNullException(nameof(room)); } var results = new List(); 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; } /// /// 房间边界的对应字典(元素-曲线)集合 /// /// /// public static Dictionary 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()); } /// /// 获取房间几何体相交的元素 /// /// /// 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); } /// /// 获取房间最外侧边界 /// /// /// 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 }; } /// /// 获取房间的几何体 /// /// /// public static Solid GetSolid(this Room room) { var doc = room.Document; var segc = new SpatialElementGeometryCalculator(doc); var segr = segc.CalculateSpatialElementGeometry(room); return segr.GetGeometry(); } /// /// 得到房间的三维实体 /// /// /// /// /// private static DirectShape RoomSolid(Room room, List 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); var solid = GeometryCreationUtilities.CreateExtrusionGeometry(curveLoops, XYZ.BasisZ, height, options); var directShape = doc.CreateDirectShapeInstance( "房间实体", BuiltInCategory.OST_GenericModel, [solid]); 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 { solid }); //room.Document.Regenerate(); var elements = new FilteredElementCollector(doc); var solidFillPattern = elements.OfClass(typeof(FillPatternElement)).Cast().First(a => a.GetFillPattern().IsSolidFill); var color = ColorAssist.GetDistinctColorById(directShape.Id); 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); doc.ActiveView.SetElementOverrides(directShape.Id, ogs); #else ogs.SetSurfaceBackgroundPatternColor(color); ogs.SetSurfaceForegroundPatternId(solidFillPattern.Id); ogs.SetSurfaceForegroundPatternColor(color); ogs.SetCutBackgroundPatternColor(color); ogs.SetCutForegroundPatternColor(color); ogs.SetCutForegroundPatternId(solidFillPattern.Id); ogs.SetSurfaceTransparency(50); doc.ActiveView.SetElementOverrides(directShape.Id, ogs); #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; // //} //} return directShape; } }