From 5a3a368a2eb0dc197caade20577786356721582a Mon Sep 17 00:00:00 2001
From: GG Z <903524121@qq.com>
Date: Sun, 22 Feb 2026 21:12:18 +0800
Subject: [PATCH] =?UTF-8?q?=E5=8A=9F=E8=83=BD=E6=9B=B4=E6=96=B0?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
ShrlAlgoToolkit.RevitAddins/Entry/RvApp.cs | 3 -
.../Mep/MappingSystemCmd.cs | 66 ++++
.../Standardizer/WriteParametersCmd.cs | 35 ++
.../Standardizer/WriteParametersView.xaml | 127 +++++++
.../Standardizer/WriteParametersView.xaml.cs | 16 +
.../Standardizer/WriteParametersViewModel.cs | 359 ++++++++++++++++++
.../Base/BaseApplication.cs | 9 +-
.../Extensions/ConnectorExtensions.cs | 2 +-
.../Extensions/ElementExtensions.cs | 247 ++++++++++++
.../Extensions/FamilyInstanceExtensions.cs | 37 ++
10 files changed, 894 insertions(+), 7 deletions(-)
create mode 100644 ShrlAlgoToolkit.RevitAddins/Mep/MappingSystemCmd.cs
create mode 100644 ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersCmd.cs
create mode 100644 ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml
create mode 100644 ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml.cs
create mode 100644 ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersViewModel.cs
diff --git a/ShrlAlgoToolkit.RevitAddins/Entry/RvApp.cs b/ShrlAlgoToolkit.RevitAddins/Entry/RvApp.cs
index ab3c085..a272d37 100644
--- a/ShrlAlgoToolkit.RevitAddins/Entry/RvApp.cs
+++ b/ShrlAlgoToolkit.RevitAddins/Entry/RvApp.cs
@@ -5,9 +5,6 @@ using ShrlAlgoToolkit.RevitAddins.FamMaster;
using ShrlAlgoToolkit.RevitAddins.ModelManager;
using ShrlAlgoToolkit.RevitAddins.Properties;
using ShrlAlgoToolkit.RevitAddins.RvCivil;
-using ShrlAlgoToolkit.RevitAddins.RvCommon;
-using ShrlAlgoToolkit.RevitAddins.RvMEP;
-using ShrlAlgoToolkit.RevitAddins.RvView;
namespace ShrlAlgoToolkit.RevitAddins.Entry;
diff --git a/ShrlAlgoToolkit.RevitAddins/Mep/MappingSystemCmd.cs b/ShrlAlgoToolkit.RevitAddins/Mep/MappingSystemCmd.cs
new file mode 100644
index 0000000..1e7b364
--- /dev/null
+++ b/ShrlAlgoToolkit.RevitAddins/Mep/MappingSystemCmd.cs
@@ -0,0 +1,66 @@
+using System.Linq;
+
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Mechanical;
+using Autodesk.Revit.DB.Plumbing;
+using Autodesk.Revit.UI;
+using Autodesk.Revit.UI.Selection;
+
+namespace Szmedi.Test
+{
+ ///
+ /// Revit执行命令
+ ///
+ [Transaction(TransactionMode.Manual)]
+ [Regeneration(RegenerationOption.Manual)]
+ public class MappingSystemCmd : IExternalCommand
+ {
+ public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
+ {
+ //程序UI界面
+ UIApplication uiapp = commandData.Application;
+ //获取元素(选择) 显示元素 视图(活动视图)管理(对象)
+ UIDocument uidoc = uiapp.ActiveUIDocument;
+ //程序
+ Autodesk.Revit.ApplicationServices.Application app = uiapp.Application;
+ //获取位置和场地 视图(多个视图)管理 获取元素(Revit 项目里的全部元素)
+ Document doc = uidoc.Document;
+ //获取所有打开文档
+ DocumentSet docset = uiapp.Application.Documents;
+ //当前视图
+ View view = doc.ActiveView;
+ var systems=new FilteredElementCollector(doc)
+ .OfClass(typeof(MEPSystem))
+ .WhereElementIsNotElementType().Cast().ToList();
+ using (Transaction tx = new Transaction(doc, "Mapping System Names"))
+ {
+ tx.Start();
+ foreach (var sys in systems)
+ {
+ var typeId = sys.GetTypeId();
+ var type = doc.GetElement(typeId) as MEPSystemType;
+ if (sys is MechanicalSystem mechanicalSystem)
+ {
+ var elementSet = mechanicalSystem.DuctNetwork;
+ foreach (Element elem in elementSet)
+ {
+ elem.LookupParameter("三级系统名称")?.Set(type.Name);
+ }
+ }
+ if (sys is PipingSystem pipingSystem)
+ {
+ var elementSet = pipingSystem.PipingNetwork;
+ foreach (Element elem in elementSet)
+ {
+ elem.LookupParameter("三级系统名称")?.Set(type.Name);
+ }
+ }
+ }
+ tx.Commit();
+ }
+
+ return Result.Succeeded;
+ }
+ }
+}
\ No newline at end of file
diff --git a/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersCmd.cs b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersCmd.cs
new file mode 100644
index 0000000..06f4d73
--- /dev/null
+++ b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersCmd.cs
@@ -0,0 +1,35 @@
+using Autodesk.Revit.Attributes;
+using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.DirectContext3D;
+
+using Nice3point.Revit.Toolkit.External;
+
+using ShrlAlgoToolkit.RevitAddins.Common.Assists;
+using ShrlAlgoToolkit.RevitAddins.Standardizer;
+
+
+namespace ShrlAlgoToolkit.RevitAddins.Standardizer
+{
+ [Transaction(TransactionMode.Manual)]
+ [Regeneration(RegenerationOption.Manual)]
+ public class WriteParametersCmd : ExternalCommand
+ {
+ public override void Execute()
+ {
+ //System.Windows.MessageBox.Show(
+ // "若当前视图不是三维且所有元素可见则不会修改参数值",
+ // "注意",
+ // System.Windows.MessageBoxButton.OK,
+ // System.Windows.MessageBoxImage.Information
+ //);
+ //WriteParametersWin win = WpfSingletonHelper.GetInstance(out bool isNewCreate);
+ //if (isNewCreate)
+ //{
+ // win.DataContext = new WriteParametersViewModel(UiDocument);
+ // win.ShowAhead();
+ //}
+ //win.Activate();
+ WinDialogAssist.ShowOrActivate(UiDocument);
+ }
+ }
+}
diff --git a/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml
new file mode 100644
index 0000000..b4ffc4c
--- /dev/null
+++ b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml
@@ -0,0 +1,127 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml.cs b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml.cs
new file mode 100644
index 0000000..03f354d
--- /dev/null
+++ b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersView.xaml.cs
@@ -0,0 +1,16 @@
+using System.Windows;
+using System.Windows.Media;
+
+namespace ShrlAlgoToolkit.RevitAddins.Standardizer
+{
+ ///
+ /// WriteParametersWin.xaml 的交互逻辑
+ ///
+ public partial class WriteParametersView
+ {
+ public WriteParametersView()
+ {
+ InitializeComponent();
+ }
+ }
+}
diff --git a/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersViewModel.cs b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersViewModel.cs
new file mode 100644
index 0000000..e934237
--- /dev/null
+++ b/ShrlAlgoToolkit.RevitAddins/Standardizer/WriteParametersViewModel.cs
@@ -0,0 +1,359 @@
+using System.Diagnostics;
+using System.IO;
+using System.Reflection;
+using System.Text;
+using System.Text.RegularExpressions;
+using System.Windows;
+
+
+using Autodesk.Revit.DB;
+
+using CommunityToolkit.Mvvm.ComponentModel;
+using CommunityToolkit.Mvvm.Input;
+
+
+using Microsoft.Win32;
+
+using MiniExcelLibs.Attributes;
+
+using Nice3point.Revit.Toolkit.External.Handlers;
+
+using ShrlAlgoToolkit.RevitAddins;
+using ShrlAlgoToolkit.RevitAddins.Common.Assists;
+using ShrlAlgoToolkit.RevitAddins.Common.Extensions;
+
+
+namespace ShrlAlgoToolkit.RevitAddins.Standardizer;
+
+public partial class WriteParametersViewModel : ObservableObject
+{
+ public WriteParametersViewModel(UIDocument uIDocument)
+ {
+ this.uiDocument = uIDocument;
+ }
+
+ private readonly ActionEventHandler handler = new();
+
+ [ObservableProperty]
+ private bool isSelectedItems;
+
+ [ObservableProperty]
+ private bool isOverride;
+
+ //record class ParameterModel(string Name, object Value);
+ [ObservableProperty]
+ [NotifyCanExecuteChangedFor(nameof(ExportExcelCommand))]
+ [NotifyCanExecuteChangedFor(nameof(WriteParamsCommand))]
+ private List items;
+
+ [ObservableProperty]
+ private string excelPath;
+ private readonly UIDocument uiDocument;
+ private bool HasItems => Items?.Any() == true;
+
+ [RelayCommand]
+ private void GetParams()
+ {
+ Items = null;
+ List models = [];
+ Document doc = uiDocument.Document;
+ try
+ {
+ Reference reference = uiDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element, "请选择提取参数的元素");
+ Element elem = doc.GetElement(reference);
+ foreach (Parameter param in elem.Parameters)
+ {
+ if (!param.HasValue || string.IsNullOrEmpty(param.AsString()))
+ {
+ models.Add(new ParameterModel() { Name = param.Definition.Name });
+ }
+ }
+
+ Items = models.OrderBy(m => m.Name).ToList();
+ }
+ catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
+ }
+
+ [RelayCommand]
+ private void OpenExcel()
+ {
+ if (ExcelPath.StartsWith("\""))
+ {
+ ExcelPath = ExcelPath.TrimStart('\"');
+ }
+ if (ExcelPath.EndsWith("\""))
+ {
+ ExcelPath = ExcelPath.TrimEnd('\"');
+ }
+ if (File.Exists(ExcelPath))
+ {
+ FileInfo file = new(ExcelPath);
+ if (file.Extension != ".xlsx")
+ {
+ MessageBox.Show("请选择xlsx格式的Excel文件");
+ }
+ else
+ {
+ ReadExcel(ExcelPath);
+ }
+ }
+ else
+ {
+ MessageBox.Show("文件路径有误");
+ }
+ }
+
+ [RelayCommand(CanExecute = nameof(HasItems))]
+ private void ExportExcel()
+ {
+ SaveFileDialog dialog =
+ new()
+ {
+ Filter = "Excel文件(xlsx)|*.xlsx",
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ };
+ if (dialog.ShowDialog() != true)
+ {
+ return;
+ }
+
+ string excel = dialog.FileName;
+ FileInfo fi = new(excel);
+ Dictionary data = new() { { "参数表", Items } };
+ data.SaveAsExcel(excel);
+ MessageBoxResult result = MessageBox.Show("是否打开Excel表?", "提示", MessageBoxButton.YesNo, MessageBoxImage.Question);
+ if (result == MessageBoxResult.Yes)
+ {
+ Process.Start(excel);
+ }
+ }
+
+ [RelayCommand(CanExecute = nameof(HasItems))]
+ private void WriteParams()
+ {
+ Document doc = uiDocument.Document;
+ List elements = IsSelectedItems
+ ? uiDocument.Selection.GetElementIds().Select(id => doc.GetElement(id)).ToList()
+ : new FilteredElementCollector(doc, doc.ActiveView.Id)
+ .WhereElementIsNotElementType()
+ .ToElements()
+ .Where(
+ e =>
+ e.CanHaveTypeAssigned()
+ && e.HasPhases()
+ && e.get_BoundingBox(doc.ActiveView) != null
+ && e.Category is { Parent: null, CategoryType: CategoryType.Model }
+ )
+ .ToList();
+
+ StringBuilder sb = new();
+ handler.Raise(_ =>
+ {
+ using (TransactionGroup transG = new(doc, "填写属性值"))
+ {
+ transG.Start();
+ foreach (Element elem in elements)
+ {
+ if (!elem.IsValidObject)
+ {
+ continue;
+ }
+ using Transaction trans = new(doc, "填写属性值");
+ //FailureHandlingOptions options = trans.GetFailureHandlingOptions();
+ //FailuresPreProcessor failuresProcessor = new();
+ //options.SetFailuresPreprocessor(failuresProcessor);
+ //trans.SetFailureHandlingOptions(options);
+ trans.Start();
+ Regex regex = new(@"^\D{2}-\d00");
+ //将“”空值填写“/”
+ foreach (Parameter parameter in elem.Parameters)
+ {
+ //if (parameter.Definition.Name == "ID-100-编号")
+ //{
+ // continue;
+ //}
+ //不为空时,跳过设置“/”
+ if (!(string.IsNullOrEmpty(parameter.AsString()) && string.IsNullOrEmpty(parameter.AsValueString())))
+ {
+ continue;
+ }
+
+ if (regex.IsMatch(parameter.Definition.Name) && !parameter.IsReadOnly)
+ {
+ if (parameter.StorageType is StorageType.Integer or StorageType.Double)
+ {
+ parameter.Set(0);
+ }
+ if (parameter.StorageType == StorageType.String)
+ {
+ parameter.Set("/");
+ }
+ }
+ }
+ doc.Regenerate();
+ //填写表单中的数据
+ foreach (ParameterModel item in Items)
+ {
+ Parameter p1 = elem.GetParameters(item.Name).FirstOrDefault();
+ if (p1 == null)
+ {
+ sb.AppendLine($"构件类别:{elem.Category};构件名:{elem.Name};构件ID:{elem.Id};参数名:{item.Name};异常原因:参数不存在");
+ continue;
+ }
+ //if (p1.Definition.Name == "ID-100-编号")
+ //{
+ // continue;
+ //}
+ try
+ {
+ if (
+ IsOverride
+ || (p1.AsString() == "/" || p1.AsValueString() == "/")
+ || (p1.AsString() == "0" || p1.AsValueString() == "0")
+ ) //如果覆盖则填写,否则不操作
+ {
+ if (p1?.IsReadOnly == false)
+ {
+ switch (p1.StorageType)
+ {
+ case StorageType.None:
+ break;
+ case StorageType.Integer:
+ p1.Set(Convert.ToInt16(item.Value));
+ break;
+ case StorageType.Double:
+ p1.Set(Convert.ToDouble(item.Value));
+ break;
+ case StorageType.String:
+ p1.Set(Convert.ToString(item.Value));
+ break;
+ case StorageType.ElementId:
+ break;
+ }
+ }
+ }
+
+ //if (p1?.IsReadOnly == false)
+ //{
+ // switch (p1.StorageType)
+ // {
+ // case StorageType.None:
+ // break;
+ // case StorageType.Integer:
+ // p1.Set(Convert.ToInt16(item.Value));
+ // break;
+ // case StorageType.Double:
+ // p1.Set(Convert.ToDouble(item.Value));
+ // break;
+ // case StorageType.String:
+ // p1.Set(Convert.ToString(item.Value));
+ // break;
+ // case StorageType.ElementId:
+ // break;
+ // }
+ //}
+ }
+ catch (Exception exception)
+ {
+ sb.AppendLine(
+ $"构件类别:{elem.Category};构件名:{elem.Name};构件ID:{elem.Id};参数名:{p1.Definition.Name};异常原因:{exception.Message}"
+ );
+ }
+ }
+ trans.Commit();
+ }
+ transG.Assimilate();
+ }
+ if (sb.Length > 0)
+ {
+ LogAssist.WriteTextFile( sb.ToString(), "修改异常问题");
+ }
+ MessageBox.Show("修改参数完成!", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
+ });
+ }
+
+ [RelayCommand]
+ private void BrowserExcelFile()
+ {
+ OpenFileDialog dialog =
+ new()
+ {
+ CheckFileExists = true,
+ Filter = "Excel文件(*.xlsx)|*.xlsx",
+ Multiselect = false,
+ InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments),
+ };
+ if (dialog.ShowDialog() != true)
+ {
+ return;
+ }
+ //Items?.Clear();
+ ExcelPath = dialog.FileName;
+ ReadExcel(dialog.FileName);
+ }
+
+ private void ReadExcel(string path)
+ {
+ Items= [.. path.ReadExcel()];
+ }
+
+ private static Assembly CurrentDomainOnAssemblyResolve(object sender, ResolveEventArgs args)
+ {
+ if (!args.Name.Contains("ComponentModel.Annotations"))
+ {
+ return null;
+ }
+
+ string assemblyFile = Path.Combine(Variables.DirAssembly, "System.ComponentModel.Annotations.dll");
+ return File.Exists(assemblyFile) ? Assembly.LoadFrom(assemblyFile) : null;
+ }
+
+ [RelayCommand]
+ private void Init(int index)
+ {
+ if (index == 0)
+ {
+ Items = GetInitCivilParameterList();
+ }
+ else
+ {
+ Items = index == 1 ? GetInitMEPParameterList() : null;
+ }
+ }
+
+ private List GetInitCivilParameterList()
+ {
+ return
+ [
+ new() { Name = "AM-200-模型权属单位", Value = "深圳市地铁集团有限公司" },
+ new() { Name = "AM-200-资产权属单位", Value = "深圳市地铁集团有限公司" },
+ new() { Name = "CM-100-创建单位", Value = "深圳市市政设计研究院有限公司" },
+ new() { Name = "ID-200-BIM对象分类编码执行标准", Value = "《城市轨道交通工程信息模型分类和编码标准》SJG102" },
+ new() { Name = "CM-100-校审单位", Value = "数云科际(深圳)技术有限公司" },
+ new() { Name = "FM-200-产品寿命", Value = "100" },
+ new() { Name = "FM-200-使用年限", Value = "100" },
+ new() { Name = "TC-400-设计使用年限", Value = "100" }
+ ];
+ }
+
+ private List GetInitMEPParameterList()
+ {
+ return
+ [
+ new() { Name = "AM-200-模型权属单位", Value = "深圳市地铁集团有限公司" },
+ new() { Name = "AM-200-资产权属单位", Value = "深圳市地铁集团有限公司" },
+ new() { Name = "CM-100-创建单位", Value = "深圳市市政设计研究院有限公司" },
+ new() { Name = "CM-100-校审单位", Value = "深圳市市政设计研究院有限公司" },
+ new() { Name = "CM-100-创建人及联系方式", Value = "/" },
+ ];
+ }
+}
+
+public class ParameterModel
+{
+ [ExcelColumn(Name="参数名")]
+ public string Name { get; set; }
+
+ [ExcelColumn(Name ="参数值")]
+ public string Value { get; set; }
+}
diff --git a/ShrlAlgoToolkit.RevitCore/Base/BaseApplication.cs b/ShrlAlgoToolkit.RevitCore/Base/BaseApplication.cs
index b1fe9ed..e8af4c9 100644
--- a/ShrlAlgoToolkit.RevitCore/Base/BaseApplication.cs
+++ b/ShrlAlgoToolkit.RevitCore/Base/BaseApplication.cs
@@ -10,11 +10,14 @@ namespace ShrlAlgoToolkit.RevitCore.Assists
{
public abstract class BaseApplication : IExternalApplication
{
- public UIControlledApplication UiApplication { get; private set; }
-
+ public UIApplication UiApplication { get; private set; }
+
public Result OnStartup(UIControlledApplication application)
{
- UiApplication = application;
+ var flag = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.InvokeMethod;
+
+ UiApplication = (Autodesk.Revit.UI.UIApplication)application.GetType().InvokeMember("getUIApplication", flag, Type.DefaultBinder, application, null);
+
// 1. 注册程序集依赖解析事件 (解决第三方库找不到的问题)
AppDomain.CurrentDomain.AssemblyResolve += OnAssemblyResolve;
diff --git a/ShrlAlgoToolkit.RevitCore/Extensions/ConnectorExtensions.cs b/ShrlAlgoToolkit.RevitCore/Extensions/ConnectorExtensions.cs
index 0caf1a0..44134b5 100644
--- a/ShrlAlgoToolkit.RevitCore/Extensions/ConnectorExtensions.cs
+++ b/ShrlAlgoToolkit.RevitCore/Extensions/ConnectorExtensions.cs
@@ -114,7 +114,7 @@ public static class ConnectorExtensions
return null;
}
}
-
+
///
/// 分支连接
///
diff --git a/ShrlAlgoToolkit.RevitCore/Extensions/ElementExtensions.cs b/ShrlAlgoToolkit.RevitCore/Extensions/ElementExtensions.cs
index 2521681..539db63 100644
--- a/ShrlAlgoToolkit.RevitCore/Extensions/ElementExtensions.cs
+++ b/ShrlAlgoToolkit.RevitCore/Extensions/ElementExtensions.cs
@@ -1,4 +1,6 @@
using Autodesk.Revit.DB;
+using Autodesk.Revit.DB.Architecture;
+using Autodesk.Revit.DB.Structure;
namespace ShrlAlgoToolkit.RevitCore.Extensions;
@@ -41,6 +43,251 @@ public static class ElementExtensions
ElementTransformUtils.MoveElement(element.Document, element.Id, vector);
return element;
}
+ public static void MoveElement(this Element item, XYZ vector)
+ {
+ if (item.Pinned || !item.IsValidObject || item == null)
+ {
+ return;
+ }
+
+ var doc = item.Document;
+ var levels = doc.OfClass().OfType().OrderBy(l => l.Elevation).ToList();
+ if (item is FamilyInstance instance)
+ {
+ var baseElev = instance.get_BoundingBox(null).Min.Z + vector.Z;
+ var topElev = instance.get_BoundingBox(null).Max.Z + vector.Z;
+ var baseLevel = GetClosetLevel(levels, baseElev);
+ var topLevel = GetClosetLevel(levels, topElev);
+
+ switch (instance.Symbol.Family.FamilyPlacementType)
+ {
+ //柱
+ case FamilyPlacementType.TwoLevelsBased:
+ {
+ instance.Location.Move(vector);
+
+ instance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM).Set(baseLevel.Id);
+ instance.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_OFFSET_PARAM).Set(baseElev - baseLevel.Elevation);
+
+ instance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM).Set(topLevel.Id);
+ instance.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_OFFSET_PARAM).Set(topElev - topLevel.Elevation);
+ }
+ break;
+ case FamilyPlacementType.ViewBased:
+ break;
+ case FamilyPlacementType.WorkPlaneBased:
+ {
+ //instance.Location.Move(vector);
+ var param = instance.get_Parameter(BuiltInParameter.INSTANCE_ELEVATION_PARAM);
+ if (param != null && !param.IsReadOnly)
+ {
+ ElementTransformUtils.MoveElement(doc, instance.Id, XYZ.BasisZ * vector.Z);
+
+ //var value = param.AsDouble() + vector.Z;
+ //param.Set(value);
+ }
+
+ doc.Regenerate();
+
+ if (instance.Host == null)
+ {
+ ElementTransformUtils.MoveElement(doc, instance.Id, vector.Flatten());
+ }
+ }
+ break;
+ case FamilyPlacementType.OneLevelBased:
+ {
+ ElementTransformUtils.MoveElement(doc, instance.Id, vector);
+ }
+ break;
+ case FamilyPlacementType.OneLevelBasedHosted:
+ {
+ var ins = doc.Create
+ .NewFamilyInstance(
+ instance.GetLocXYZ(),
+ instance.Symbol,
+ instance.Host,
+ baseLevel,
+ StructuralType.NonStructural);
+ ins.get_Parameter(BuiltInParameter.INSTANCE_SILL_HEIGHT_PARAM)
+ .Set(baseElev - baseLevel.Elevation);
+ doc.Delete(instance.Id);
+ }
+ break;
+ case FamilyPlacementType.CurveBased:
+ {
+ instance.Location.Move(vector);
+ //var loc = instance.GetLocCurve().CreateTransformed(Transform.CreateTranslation(vector)) as Line;
+ //doc.Create.NewFamilyInstance(instance.HostFace, loc, instance.Symbol);
+ //doc.Delete(instance.Id);
+ }
+ break;
+ case FamilyPlacementType.CurveBasedDetail:
+ break;
+ //梁
+ case FamilyPlacementType.CurveDrivenStructural:
+ {
+ //instance.Location.Move(vector);
+ var loc = instance.GetCurve().CreateTransformed(Autodesk.Revit.DB.Transform.CreateTranslation(vector));
+ //var newLoc =
+ doc.Create.NewFamilyInstance(loc, instance.Symbol, baseLevel, StructuralType.Beam);
+ doc.Delete(instance.Id);
+
+ //ElementTransformUtils.MoveElement(doc, instance.Id, vector.Flatten());
+ }
+ break;
+ case FamilyPlacementType.Adaptive:
+ break;
+ case FamilyPlacementType.Invalid:
+ break;
+ default:
+ break;
+ }
+ }
+ else if (item is Wall wall)
+ {
+ var flat = vector.Flatten();
+ ElementTransformUtils.MoveElement(doc, wall.Id, flat);
+ doc.Regenerate();
+ SetWallHeight(vector, levels, wall);
+ var elemIds = wall.FindInserts(true, true, true, true);
+ foreach (var id in elemIds)
+ {
+ var elem = doc.GetElement(id);
+ if (elem is Wall nestWall)
+ {
+ SetWallHeight(vector, levels, nestWall);
+ }
+ else
+ {
+ MoveElement(elem, vector);
+ }
+ }
+ //墙饰条
+ var sweeps = doc.OfClass
+ ().OfType().Where(s => s.GetHostIds().Contains(wall.Id));
+ foreach (var sweep in sweeps)
+ {
+ //ElementTransformUtils.MoveElement(doc, sweep.Id, flat);
+ var boundingBox = sweep.get_BoundingBox(null);
+ var offset = boundingBox.Min.Z + vector.Z;
+
+ var baseLevel = levels.First(l => Math.Abs(l.Elevation - offset) == levels.Min(l => Math.Abs(l.Elevation - offset)));
+ sweep.get_Parameter(BuiltInParameter.WALL_SWEEP_LEVEL_PARAM).Set(baseLevel.Id);
+ sweep.get_Parameter(BuiltInParameter.WALL_SWEEP_OFFSET_PARAM).Set(offset - baseLevel.Elevation);
+ }
+ //依附在墙上的实例
+ var instances = doc.OfClass().OfType().Where(s =>
+ {
+
+ var stackedWallIds = wall.GetStackedWallMemberIds();
+ if (stackedWallIds.Count > 0)
+ {
+ return stackedWallIds.Any(id => s.Host?.Id == id);
+ }
+ return s.Host?.Id == wall.Id;
+ }).ToList();
+ foreach (var ins in instances)
+ {
+ //ins.Location.Move(vector);
+ ElementTransformUtils.MoveElement(doc, ins.Id, vector.Z * XYZ.BasisZ);
+ }
+
+ //ElementTransformUtils.CopyElements(v1, [wall.Id], v2, Transform.Identity, new CopyPasteOptions());
+ //var b = wall.Location.Move(vector);
+
+ //var loc = wall.GetLocCurve();
+ //var c = loc.CreateTransformed(Transform.CreateTranslation(vector));
+ //(wall.Location as LocationCurve).Curve = c; //可以移动,但是偏移量属性没更新
+ }
+ else if (item is Room room)
+ {
+ }
+ else if (item is Stairs stairs)
+ {
+ var flat = vector.Flatten();
+ ElementTransformUtils.MoveElement(doc, item.Id, flat);
+ }
+ else if (item is ModelCurve curve)//房间分割
+ {
+
+ }
+ else if (item is Railing railing)
+ {
+ if (railing.HasHost)
+ {
+
+ }
+ else//连带主体移动
+ {
+ ElementTransformUtils.MoveElement(doc, item.Id, vector);
+ }
+ }
+ //坡道
+ else if (item.Category.ToBuiltInCategory() == BuiltInCategory.OST_Ramps)
+ {
+ var flat = vector.Flatten();
+ ElementTransformUtils.MoveElement(doc, item.Id, flat);
+ }
+ else if (item is TopographySurface surface)
+ {
+ }
+ else if (item is SlabEdge or Fascia or Gutter)
+ {
+ return;
+ }
+ //else if (item is CeilingAndFloor ceilingAndFloor)
+ //{
+ // ElementTransformUtils.MoveElement(doc, ceilingAndFloor.Id, vector);
+ //}
+ else if (item is Opening opening)
+ {
+ if (opening.Host is Wall)
+ {
+ ElementTransformUtils.MoveElement(doc, opening.Id, vector.Z * XYZ.BasisZ);
+ }
+ }
+ else
+ {
+ ElementTransformUtils.MoveElement(doc, item.Id, vector);
+ }
+ }
+ ///
+ /// 设置墙高度
+ ///
+ ///
+ ///
+ ///
+ private static void SetWallHeight(XYZ vector, List levels, Wall wall)
+ {
+ var boundingBox = wall.get_BoundingBox(null);
+ //底部实际高度
+ var bottomElev = boundingBox.Min.Z + vector.Z;
+ var topElev = boundingBox.Max.Z + vector.Z;
+ //查找距离底部偏移最近的Level
+ var baseLevel = GetClosetLevel(levels, bottomElev);
+ wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).Set(baseLevel.Id);
+ wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(bottomElev - baseLevel.Elevation);
+ //是否有顶部约束
+ var topContraint = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
+ if (topContraint != ElementId.InvalidElementId)
+ {
+ var topLevel = GetClosetLevel(levels, topElev);
+
+ wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).Set(topLevel.Id);
+ wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).Set(topElev - topLevel.Elevation);
+ }
+ }
+ ///
+ /// 获取距离最近的标高
+ ///
+ ///
+ /// 高度
+ ///
+ private static Level GetClosetLevel(List levels, double elev)
+ {
+ return levels.First(l => Math.Abs(l.Elevation - elev) == levels.Min(l => Math.Abs(l.Elevation - elev)));
+ }
///
/// 旋转元素
///
diff --git a/ShrlAlgoToolkit.RevitCore/Extensions/FamilyInstanceExtensions.cs b/ShrlAlgoToolkit.RevitCore/Extensions/FamilyInstanceExtensions.cs
index 0b12b40..eb45e5d 100644
--- a/ShrlAlgoToolkit.RevitCore/Extensions/FamilyInstanceExtensions.cs
+++ b/ShrlAlgoToolkit.RevitCore/Extensions/FamilyInstanceExtensions.cs
@@ -43,7 +43,44 @@ internal static class FamilyInstanceExtensions
}
}
}
+ ///
+ /// 是否已连接
+ ///
+ ///
+ ///
+ public static bool IsConnectToSystem(this FamilyInstance ins)
+ {
+ bool hasConnectToSystem = false;
+ if (ins.Category.CategoryType != CategoryType.Model)
+ {
+ return true;
+ }
+ if (ins.get_BoundingBox(null) != null &&
+ ins.MEPModel?.ConnectorManager != null)
+ {
+ var cons = ins.GetConnectors(false);
+ foreach (Connector con in cons)
+ {
+ if (con.Domain != Domain.DomainElectrical && con.Domain != Domain.DomainUndefined)
+ {
+ try
+ {
+ if (con.IsConnected)
+ {
+ hasConnectToSystem = true;
+ }
+ }
+ catch (Exception)
+ {
+
+ }
+ }
+ }
+ }
+ return hasConnectToSystem;
+
+ }
public static void Rotate(this Autodesk.Revit.DB.FamilyInstance familyInstance, double radian)
{
var axis = Line.CreateBound(familyInstance.GetTransform().Origin, familyInstance.GetTransform().Origin + XYZ.BasisZ);