Files
Shrlalgo.RvKits/ShrlAlgoToolkit.RevitAddins/RvCivil/FloorFinishesViewModel.cs
2025-04-24 20:56:44 +08:00

132 lines
4.5 KiB
C#

using System.ComponentModel.DataAnnotations;
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;
namespace ShrlAlgoToolkit.RevitAddins.RvCivil;
public partial class FloorFinishesViewModel : ObservableValidator
{
public FloorFinishesViewModel(IList<FloorType> floorTypes)
{
FloorTypes = floorTypes;
finishesHandler = new ActionEventHandler();
}
private readonly ActionEventHandler finishesHandler;
//private double floorOffset;
[Required]
[Range(-6000, 6000, ErrorMessage = "输入偏移量值范围有误")]
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.FloorFinishesViewModel.PlaceFloorCommand))]
[NotifyDataErrorInfo]
[ObservableProperty]
private double floorOffset;
//[CustomValidation(typeof(FloorFinishesViewModel), nameof(ValidateFloorOffset))]
//public double FloorOffset
//{
// get => floorOffset;
// set
// {
// SetProperty(ref floorOffset, value, true);
// PlaceFloorCommand.NotifyCanExecuteChanged();
// }
//}
//自定义验证方法
//public static ValidationResult ValidateFloorOffset(string floorOffset, ValidationContext context)
//{
// FloorFinishesViewModel instance = (FloorFinishesViewModel)context.ObjectInstance;
// bool isValid = double.TryParse(floorOffset, out var _);
// if (isValid)
// {
// return ValidationResult.Success;
// }
// return new("输入内容不是数值。");
//}
[ObservableProperty] private bool rbAllRooms;
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.FloorFinishesViewModel.PlaceFloorCommand))]
private FloorType selectedFloorType;
private bool CanPlace => SelectedFloorType != null && !HasErrors;
public IList<FloorType> FloorTypes { get; }
private IEnumerable<Room> selectedRooms;
[RelayCommand(CanExecute = nameof(CanPlace))]
private void PlaceFloor()
{
finishesHandler.Raise(app =>
{
var uidoc = app.ActiveUIDocument;
GetRoomsToPlace(uidoc);
CreateFloors(uidoc);
});
}
public void CreateFloors(UIDocument uidoc)
{
var document = uidoc.Document;
document.Invoke(_ =>
{
foreach (var room in selectedRooms)
{
if (room != null && room.UnboundedHeight != 0.0)
{
//UnitFormatUtils.TryParse(document.GetUnits(), UnitType.UT_Length, FloorOffset, out double value);
var option = new SpatialElementBoundaryOptions
{
SpatialElementBoundaryLocation = SpatialElementBoundaryLocation.Finish
};
var blists = room.GetBoundarySegments(option);
CurveArray curveArray = new();
var loops = new List<CurveLoop>();
foreach (var bs in blists[0])
{
curveArray.Append(bs.GetCurve());
}
foreach (var bsList in blists)
{
var curveList = new List<Curve>();
foreach (var bs in bsList)
{
curveList.Add(bs.GetCurve());
}
loops.Add(CurveLoop.Create(curveList));
}
var level = document.GetElement(room.LevelId) as Level;
if (curveArray.Size != 0)
{
#if REVIT2018 || REVIT2020
document.Create.NewFloor(curveArray, SelectedFloorType, level, false)
#elif REVIT2025
Floor.Create(document, loops, SelectedFloorType.Id,level.Id,false,null,0.0)
#endif
.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).Set(FloorOffset / 304.8);
}
}
}
}, "房间饰面");
}
private void GetRoomsToPlace(UIDocument uidoc)
{
var doc = uidoc.Document;
selectedRooms = RbAllRooms
? (from elem in new FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(typeof(SpatialElement))
let room = elem as Room
select room)
: uidoc.SelectObjectsByRectangle<Room>("请框选以选择房间");
}
}