Files
SzmediTools/Szmedi.RvKits/ModelManager/MoveModelCmd.cs

219 lines
9.3 KiB
C#
Raw Normal View History

2025-09-16 16:06:41 +08:00

using System.Linq;
using System.Text;
using System.Windows;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI.Selection;
using Nice3point.Revit.Toolkit.External;
namespace Szmedi.RvKits.ModelManager
{
[Transaction(TransactionMode.Manual)]
public class MoveModelCmd : ExternalCommand
{
private static bool IsSketchedStairsRun(Stairs stairs)
{
var id = stairs.GetStairsRuns().FirstOrDefault();
if (id == null) return false;
var run = stairs.Document.GetElement(id) as StairsRun;
return run?.StairsRunStyle == StairsRunStyle.Sketched;
}
public override void Execute()
{
//基于面主体的图元,不进行移动
var elementsBaseFace = Document.OfClass<FamilyInstance>()
.Where(
e => e is FamilyInstance ins &&
ins.Symbol.Family.FamilyPlacementType == FamilyPlacementType.WorkPlaneBased &&
ins.Host == null &&
ins.HostFace == null);
var ids = elementsBaseFace.Select(e => e.Id).ToList();
var collector = Document
.OfParentModelCollector();
if (ids.Count > 0)
{
collector = collector.Excluding(ids);
}
var elems = collector.Where(
element => element.GetType() != typeof(RevitLinkInstance) &&
element.GroupId == ElementId.InvalidElementId)
.ToList();
if (elems == null)
{
MessageBox.Show("没有找到模型元素", "错误");
return;
}
//组
var groups = Document.QueryElementsByType<Group>().WhereElementIsNotElementType().ToElements();
//var basePoints = doc.QueryElementsByType<BasePoint>().ToElements();
//标高
var levels = Document.QueryElementsByType<Level>().WhereElementIsNotElementType().ToElements();
//线条
var modelCurve = new FilteredElementCollector(Document).OfCategory(BuiltInCategory.OST_Lines).WhereElementIsNotElementType().ToElements();
//视图
var viewers = Document.QueryElementsByCategory(BuiltInCategory.OST_Viewers).WhereElementIsNotElementType().ToElements();
//常规注释族
var annotations = Document.QueryElementsByCategory(BuiltInCategory.OST_GenericAnnotation).WhereElementIsNotElementType().ToElements();
//立面
var elevs = Document.QueryElementsByCategory(BuiltInCategory.OST_Elev).WhereElementIsNotElementType().ToElements();
//轴网
var grids = Document.QueryElementsByType<Grid>().WhereElementIsNotElementType().ToElements();
//尺寸标注
var dims = Document.QueryElementsByType<Dimension>().WhereElementIsNotElementType().ToElements();
//文字
var texts = Document.QueryElementsByType<TextNote>().WhereElementIsNotElementType().ToElements();
//标记
var tags = Document.QueryElementsByType<IndependentTag>().WhereElementIsNotElementType().ToElements();
//填充
var fillRegions = Document.QueryElementsByType<FilledRegion>().WhereElementIsNotElementType().ToElements();
//洞口
var openings = Document.QueryElementsByType<Opening>().Cast<Opening>().Where(open => open.Host is Floor).ToList();
var importInstances = Document.QueryElementsByType<ImportInstance>().Cast<ImportInstance>().ToList();
elems.AddRange(groups);
//elems.AddRange(basePoints);
elems.AddRange(modelCurve);
elems.AddRange(levels);
elems.AddRange(grids);
elems.AddRange(viewers);
elems.AddRange(elevs);
elems.AddRange(dims);
elems.AddRange(annotations);
elems.AddRange(texts);
elems.AddRange(tags);
elems.AddRange(fillRegions);
elems.AddRange(openings);
elems.AddRange(importInstances);
var elemIds = elems.ConvertAll(element => element.Id);
if (elems.Count == 0)
{
return;
}
StringBuilder sb = new StringBuilder();
Document.Invoke(_ =>
{
foreach (var element in elems)
{
if (element is Group g && g.GroupId != ElementId.InvalidElementId)//嵌套组
{
continue;
}
if (element.Pinned)
{
try
{
element.Pinned = false;
}
catch (Autodesk.Revit.Exceptions.InvalidOperationException)
{
}
}
}
Document.Regenerate();
const ObjectSnapTypes snapSettings =
ObjectSnapTypes.Endpoints
| ObjectSnapTypes.Midpoints
| ObjectSnapTypes.Intersections
| ObjectSnapTypes.Tangents
| ObjectSnapTypes.Quadrants
| ObjectSnapTypes.Points
| ObjectSnapTypes.Perpendicular
| ObjectSnapTypes.Nearest
| ObjectSnapTypes.Centers;
try
{
var originWorkPlane = ActiveView.SketchPlane;
var sketch = ActiveView.SketchPlane;
if (ActiveView is ViewSection section)
{
section.SketchPlane = SketchPlane.Create(
Document,
Plane.CreateByNormalAndOrigin(ActiveView.ViewDirection, XYZ.Zero)
);
Document.Regenerate();
}
var origin = UiDocument.Selection.PickPoint(snapSettings, "请点选模型移动的起点(起点)");
var target = UiDocument.Selection.PickPoint(snapSettings, "请点选模型移动的目标点(终点)");
//Thread.Sleep(1_000);
var coordinationResult = MessageBox.Show(
$"起点坐标:{origin * 304.8}mm\n终点坐标{target * 304.8}mm",
"确认坐标是否无误并进行移动?",
MessageBoxButton.YesNo,
MessageBoxImage.Question
);
//if (Math.Abs(target.Z - origin.Z) > 10e-6)
//{
// var stairs = elems.Where(e => e is Stairs stairs && IsSketchedStairsRun(stairs)).ToList();
// if (stairs.Count > 0)
// {
// MessageBox.Show("草图绘制的楼梯无法上下移动,请先剪切到剪切板,避免移动后被删除", "警告");
// UiDocument.Selection.SetElementIds(stairs.ConvertAll(e => e.Id));
// return;
// }
//}
if (coordinationResult == MessageBoxResult.Yes)
{
var translateXyz = target - origin;
try
{
ElementTransformUtils.MoveElements(Document, elemIds, translateXyz);
}
catch (Exception)
{
MessageBox.Show("模型移动失败,请检查是否有无法移动的图元", "错误");
}
//foreach (var item in elemIds)
//{
// try
// {
// ElementTransformUtils.MoveElement(Document, item, translateXyz);
// }
// catch (Exception)
// {
// sb.AppendLine($"元素ID{item},{Document.GetElement(item).Name},图元移动失败,");
// }
//}
}
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
}, "移动模型");
if (elementsBaseFace.Any())
{
foreach (var elem in elementsBaseFace)
{
2025-09-19 09:18:09 +08:00
sb.AppendLine($"{elem.Id},{elem.Name},基于面主体的图元,不进行移动,但可能会因为主体移动而错位,请检查,");
2025-09-16 16:06:41 +08:00
}
}
if (sb.Length > 0)
{
File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\移动模型失败.csv", sb.ToString(), Encoding.UTF8);
MessageBox.Show(
$"部分图元无法移动,请查阅桌面 移动模型失败 文件:\n{sb}",
"提醒",
MessageBoxButton.OK,
MessageBoxImage.Information
);
}
}
}
}