更新整理
This commit is contained in:
279
ShrlAlgoToolkit.Revit/Extensions/RoomExtensions.cs
Normal file
279
ShrlAlgoToolkit.Revit/Extensions/RoomExtensions.cs
Normal file
@@ -0,0 +1,279 @@
|
||||
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>
|
||||
/// 得到房间的三位实体
|
||||
/// </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);
|
||||
|
||||
var ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_GenericModel));
|
||||
ds.SetName(room.Name);
|
||||
var option = ds.GetOptions();
|
||||
option.ReferencingOption = DirectShapeReferencingOption.NotReferenceable;
|
||||
ds.SetOptions(option);
|
||||
ds.AppendShape(new List<GeometryObject> { solid });
|
||||
room.Document.Regenerate();
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user