2025-04-24 20:56:44 +08:00
|
|
|
|
using Autodesk.Revit.DB;
|
|
|
|
|
|
using Autodesk.Revit.DB.Architecture;
|
|
|
|
|
|
|
|
|
|
|
|
namespace ShrlAlgoToolkit.Revit.Assists;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/// <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);
|
|
|
|
|
|
options = new SolidOptions(material.Id, ElementId.InvalidElementId);
|
|
|
|
|
|
var solid = GeometryCreationUtilities.CreateExtrusionGeometry(curveLoops, XYZ.BasisZ, height);
|
|
|
|
|
|
|
2025-07-11 09:20:23 +08:00
|
|
|
|
var directShape = doc.CreateDirectShapeInstance(
|
|
|
|
|
|
"房间实体",
|
|
|
|
|
|
BuiltInCategory.OST_GenericModel,
|
|
|
|
|
|
new List<GeometryObject> { solid });
|
|
|
|
|
|
directShape.get_Parameter(BuiltInParameter.DOOR_NUMBER).Set(room.Name);
|
2025-07-12 23:31:32 +08:00
|
|
|
|
var ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
|
2025-07-11 09:20:23 +08:00
|
|
|
|
//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);
|
|
|
|
|
|
|
|
|
|
|
|
var random = new Random(DateTime.Now.Millisecond);
|
|
|
|
|
|
var r = Convert.ToByte(random.Next(0, 255));
|
|
|
|
|
|
var g = Convert.ToByte(random.Next(0, 255));
|
|
|
|
|
|
var b = Convert.ToByte(random.Next(0, 255));
|
|
|
|
|
|
var color = new Color(r, g, b);
|
|
|
|
|
|
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(ds.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(ds.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 ds;
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|