171 lines
6.9 KiB
C#
171 lines
6.9 KiB
C#
using Autodesk.Revit.DB;
|
|
using Autodesk.Revit.DB.Architecture;
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
using Nice3point.Revit.Toolkit.External.Handlers;
|
|
|
|
using ShrlAlgoToolkit.RevitAddins.RvMEP;
|
|
using ShrlAlgoToolkit;
|
|
using ShrlAlgoToolkit.RevitAddins;
|
|
|
|
//using RandomColorGenerator;
|
|
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.Mep;
|
|
|
|
public partial class HeadroomCheckViewModel : ObservableObject
|
|
{
|
|
private readonly UIApplication uiapp;
|
|
|
|
public HeadroomCheckViewModel(UIApplication uiapp)
|
|
{
|
|
this.uiapp = uiapp;
|
|
document = uiapp.ActiveUIDocument.Document;
|
|
Rooms = GetRoomItems();
|
|
checkHeadroom = new ActionEventHandler();
|
|
generateRoom3d = new ActionEventHandler();
|
|
}
|
|
private readonly ActionEventHandler checkHeadroom;
|
|
private readonly ActionEventHandler generateRoom3d;
|
|
private readonly Document document;
|
|
|
|
[ObservableProperty]
|
|
public partial List<RoomCheckItem> Rooms { get; set; }
|
|
|
|
private List<RoomCheckItem> GetRoomItems()
|
|
{
|
|
var roomItems = new List<RoomCheckItem>();
|
|
var allRooms = uiapp.ActiveUIDocument.Document.OfClass<SpatialElement>().OfType<Room>();
|
|
var groups = allRooms.GroupBy(r => r.Name);
|
|
IEnumerable<IGrouping<string, Room>> enumerable = groups as IGrouping<string, Room>[] ?? groups.ToArray();
|
|
for (int i = 0; i < enumerable.Count(); i++)
|
|
{
|
|
var group = enumerable.ElementAt(i);
|
|
foreach (var room in group)
|
|
{
|
|
var r = new RoomCheckItem()
|
|
{
|
|
Room = room,
|
|
Name = room.Name,
|
|
};
|
|
roomItems.Add(r);
|
|
}
|
|
}
|
|
return roomItems;
|
|
}
|
|
private bool CanClick()
|
|
{
|
|
return Rooms is { Count: > 0 };
|
|
}
|
|
[RelayCommand(CanExecute = nameof(CanClick))]
|
|
private void AnalysisHeadroom()
|
|
{
|
|
checkHeadroom.Raise(_ =>
|
|
{
|
|
var view = document.ActiveView;
|
|
//var elev = view.GenLevel.Bottom;
|
|
document.Invoke(_ =>
|
|
{
|
|
ElementClassFilter filter = new(typeof(Floor));
|
|
foreach (var item in Rooms)
|
|
{
|
|
var room = item.Room;
|
|
Level baseLevel = room.Level;
|
|
var levels = document.OfClass<Level>().Cast<Level>();
|
|
Level aboveLevel = null;
|
|
double tempElev = double.MaxValue;
|
|
foreach (var level in levels)
|
|
{
|
|
if (level.Elevation > baseLevel.Elevation && (level.Elevation - baseLevel.Elevation) < tempElev)
|
|
{
|
|
aboveLevel = level;
|
|
tempElev = level.Elevation;
|
|
}
|
|
}
|
|
|
|
Element hitBottomElement = null;
|
|
Element hitTopElement = null;
|
|
document.XRayFindNearest(filter, FindReferenceTarget.Element, room.GetLocXYZ(), -XYZ.BasisZ, ref hitBottomElement);
|
|
document.XRayFindNearest(filter, FindReferenceTarget.Element, room.GetLocXYZ(), XYZ.BasisZ, ref hitTopElement);
|
|
if (hitBottomElement is Floor bottomFloor && bottomFloor.LevelId == baseLevel.Id)//击中的楼板是上层的楼板
|
|
{
|
|
//绝对标高
|
|
var baseOffset = bottomFloor.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_BOTTOM).AsDouble();
|
|
//底部偏移
|
|
room.BaseOffset = baseOffset - baseLevel.Elevation;
|
|
}
|
|
else//找不到楼板则为0
|
|
{
|
|
room.BaseOffset = 0;
|
|
}
|
|
|
|
if (hitTopElement is Floor topFloor && topFloor.LevelId == aboveLevel?.Id)//击中的楼板是当前的楼板
|
|
{
|
|
//绝对标高
|
|
var limitOffset = topFloor.get_Parameter(BuiltInParameter.STRUCTURAL_ELEVATION_AT_TOP).AsDouble();
|
|
//高度偏移
|
|
room.LimitOffset = limitOffset - room.UpperLimit.Elevation;
|
|
//全部高度
|
|
//view.GetViewRange().GetLevelId(PlanViewPlane.TopClipPlane)
|
|
//item.Room
|
|
}
|
|
else//找不到楼板则为上部标高
|
|
{
|
|
room.LimitOffset = aboveLevel.Elevation - room.UpperLimit.Elevation;
|
|
}
|
|
document.Regenerate();
|
|
var elements = room.GetIntersectElements().Where(e => e is MEPCurve || e.Category.Id == new ElementId(BuiltInCategory.OST_StructuralFraming));
|
|
foreach (var elem in elements)
|
|
{
|
|
var boundingBox = elem.get_BoundingBox(view);
|
|
//最低绝对标高
|
|
var roomTopOffset = boundingBox.Min.Z;
|
|
room.LimitOffset = roomTopOffset - room.UpperLimit.Elevation;
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
[RelayCommand(CanExecute = nameof(CanClick))]
|
|
private void GenerateRoom3D()
|
|
{
|
|
document.Invoke(_ =>
|
|
{
|
|
var list = new List<GeometryObject>();
|
|
DirectShape ds = DirectShape.CreateElement(document, new ElementId(BuiltInCategory.OST_GenericModel));
|
|
FillPatternElement solidFillPattern = document
|
|
.OfClass<FillPatternElement>()
|
|
.Cast<FillPatternElement>()
|
|
.FirstOrDefault(a => a.GetFillPattern().IsSolidFill);
|
|
foreach (var item in Rooms)
|
|
{
|
|
list.Add(item.Room.GetSolid());
|
|
Color color = item.Color;
|
|
//TextNote.Create(document, viewId, position, text, options)
|
|
OverrideGraphicSettings ogs = new();
|
|
ogs.SetProjectionLineColor(color);
|
|
#if REVIT2018
|
|
ogs.SetSurfaceTransparency(50);
|
|
ogs.SetProjectionFillColor(color);
|
|
ogs.SetProjectionFillPatternId(solidFillPattern.Id);
|
|
|
|
ogs.SetCutFillColor(color);
|
|
ogs.SetCutFillPatternId(solidFillPattern.Id);
|
|
document.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);
|
|
document.ActiveView.SetElementOverrides(ds.Id, ogs);
|
|
#endif
|
|
}
|
|
ds.AppendShape(list);
|
|
}, "创建三维房间实体");
|
|
}
|
|
} |