Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/RvMEP/MoveMEPCurveViewModel.cs
2025-04-24 20:56:10 +08:00

167 lines
5.3 KiB
C#

using Autodesk.Revit.DB;
using Autodesk.Revit.UI.Selection;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Nice3point.Revit.Toolkit.External.Handlers;
using ShrlAlgoToolkit.Mvvm.Attributes;
namespace ShrlAlgo.RvKits.RvMEP;
public partial class MoveMEPCurveViewModel : ObservableValidator
{
[ObservableProperty]
private bool isSingle = true;
[ObservableProperty]
private bool byDistance = true;
private readonly ActionEventHandler moveHandler = new();
[IsNumeric]
[ObservableProperty]
[NotifyDataErrorInfo]
private double distance;
//public double Distance
//{
// get => distance;
// set => SetProperty(ref distance, value, true);
//}
/// <summary>
/// 正在执行命令
/// </summary>
[ObservableProperty]
[NotifyCanExecuteChangedFor(nameof(MoveCommand))]
private bool canRunning = true;
[RelayCommand]
private void Closing()
{
#region 退
if (!CanRunning)
{
KeyIntPtrHelper.RaiseEscTwice();
}
#endregion
}
[RelayCommand]
private void Select()
{
moveHandler.Raise(uiapp =>
{
var uiDocument = uiapp.ActiveUIDocument;
var doc = uiDocument.Document;
try
{
var reference = uiDocument.Selection.PickObject(ObjectType.Element, new GenericFilter<MEPCurve>(), "请选择移动管线");
var mepCurve = doc.GetElement(reference) as MEPCurve;
var ids = new List<ElementId>();
mepCurve.GetAllConnectedElements(ids);
uiDocument.Selection.SetElementIds(ids);
}
catch (Exception)
{
return;
}
CanRunning = true;
});
}
[RelayCommand]
private void Move()
{
CanRunning = false;
moveHandler.Raise(uiapp =>
{
var uiDocument = uiapp.ActiveUIDocument;
var doc = uiDocument.Document;
doc.Invoke(
_ =>
{
double z;
MEPCurve mepCurve;
try
{
var reference = uiDocument.Selection.PickObject(ObjectType.Element, new GenericFilter<MEPCurve>(), "请选择移动管线");
mepCurve = doc.GetElement(reference) as MEPCurve;
}
catch (Exception)
{
CanRunning = true;
return;
}
if (ByDistance)
{
z = Distance / 304.8;
}
else
{
Reference reference = null;
ElementInLinkOrCurrentDocument linkOrCurrentDocument = new(doc);
try
{
reference = uiDocument.Selection.PickObject(ObjectType.PointOnElement, linkOrCurrentDocument, "请选择基准元素");
}
catch (Exception)
{
// ignored
}
if (reference == null)
{
CanRunning = true;
return;
}
var referenceElem = linkOrCurrentDocument.LastCheckedWasFromLink
? linkOrCurrentDocument.LinkedDocument.GetElement(reference.LinkedElementId)
: doc.GetElement(reference);
var referMaxZ = referenceElem.get_BoundingBox(doc.ActiveView).Max.Z;
var referMinZ = referenceElem.get_BoundingBox(doc.ActiveView).Min.Z;
var maxZ = mepCurve.get_BoundingBox(doc.ActiveView).Max.Z;
var minZ = mepCurve.get_BoundingBox(doc.ActiveView).Min.Z;
//参考底部大于原管线顶部
if (referMinZ > maxZ)
{
z = (referMinZ - Math.Abs(Distance) / 304.8) - maxZ;
}
//参考顶部大于原管线底部
else if (referMaxZ < minZ)
{
z = (referMaxZ + Math.Abs(Distance) / 304.8) - minZ;
}
else
{
CanRunning = true;
return;
}
}
if (IsSingle)
{
ElementTransformUtils.MoveElement(doc, mepCurve.Id, XYZ.BasisZ * z);
}
else
{
var ids = new List<ElementId>();
mepCurve.GetAllConnectedElements(ids);
ElementTransformUtils.MoveElements(doc, ids, XYZ.BasisZ * z);
}
},
"移动管线"
);
CanRunning = true;
});
}
}