Files
SzmediTools/Szmedi.RvKits/ModelManager/MoveModelCmd.cs
2025-09-16 16:06:41 +08:00

219 lines
9.2 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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)
{
sb.AppendLine($"{elem.Id},{elem.Name},基于面主体的图元,不进行移动,");
}
}
if (sb.Length > 0)
{
File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\移动模型失败.csv", sb.ToString(), Encoding.UTF8);
MessageBox.Show(
$"部分图元无法移动,请查阅桌面 移动模型失败 文件:\n{sb}",
"提醒",
MessageBoxButton.OK,
MessageBoxImage.Information
);
}
}
}
}