Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/RvMEP/HeadroomCheckViewModel.cs

178 lines
7.2 KiB
C#
Raw Normal View History

2024-09-22 11:05:41 +08:00
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Nice3point.Revit.Toolkit.External.Handlers;
using RandomColorGenerator;
namespace ShrlAlgo.RvKits.RvMEP;
2024-09-22 11:05:41 +08:00
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]
private List<RoomCheckItem> rooms;
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();
var colors = GetRandomColors(enumerable.Count());
for (int i = 0; i < enumerable.Count(); i++)
{
var group = enumerable.ElementAt(i);
var color = colors.ElementAt(i);
foreach (var room in group)
{
var r = new RoomCheckItem()
{
Room = room,
Name = room.Name,
Color = color,
};
roomItems.Add(r);
}
}
return roomItems;
}
private static IEnumerable<Color> GetRandomColors(int count)
{
var colors = RandomColor.GetColors(ColorScheme.Random, Luminosity.Light, count);
return colors.Select(color => new Color(color.R, color.G, color.B));
}
private bool CanClick()
{
return Rooms.Any();
}
[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);
}, "创建三维房间实体");
}
}