2024-09-22 11:05:41 +08:00
|
|
|
|
using System.ComponentModel.DataAnnotations;
|
|
|
|
|
|
using Autodesk.Revit.DB;
|
|
|
|
|
|
using Autodesk.Revit.DB.Architecture;
|
|
|
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
|
|
using Nice3point.Revit.Toolkit.External.Handlers;
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-04-24 20:56:44 +08:00
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.RvCivil;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
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 = "输入偏移量值范围有误")]
|
2025-04-24 20:56:44 +08:00
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.FloorFinishesViewModel.PlaceFloorCommand))]
|
2024-09-22 11:05:41 +08:00
|
|
|
|
[NotifyDataErrorInfo]
|
|
|
|
|
|
[ObservableProperty]
|
2025-10-04 08:52:23 +08:00
|
|
|
|
public partial double FloorOffset { get; set; }
|
|
|
|
|
|
|
2024-09-22 11:05:41 +08:00
|
|
|
|
//[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("输入内容不是数值。");
|
|
|
|
|
|
//}
|
|
|
|
|
|
|
2025-10-04 08:52:23 +08:00
|
|
|
|
[ObservableProperty]
|
|
|
|
|
|
public partial bool RbAllRooms { get; set; }
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
2025-04-24 20:56:44 +08:00
|
|
|
|
[NotifyCanExecuteChangedFor(nameof(RevitAddins.RvCivil.FloorFinishesViewModel.PlaceFloorCommand))]
|
2025-10-04 08:52:23 +08:00
|
|
|
|
public partial FloorType SelectedFloorType { get; set; }
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
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>("请框选以选择房间");
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|