409 lines
17 KiB
C#
409 lines
17 KiB
C#
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.IO;
|
||
using System.Linq;
|
||
using System.Text;
|
||
using System.Text.RegularExpressions;
|
||
using System.Windows;
|
||
using System.Windows.Interop;
|
||
using System.Windows.Media;
|
||
|
||
using Autodesk.Revit.Attributes;
|
||
using Autodesk.Revit.DB;
|
||
using Autodesk.Revit.DB.Architecture;
|
||
using Autodesk.Revit.DB.Structure;
|
||
using Autodesk.Revit.UI;
|
||
using Autodesk.Windows;
|
||
|
||
using Nice3point.Revit.Toolkit.External;
|
||
|
||
//using Szmedi.Toolkit.Assists;
|
||
|
||
|
||
|
||
namespace Szmedi.Test
|
||
{
|
||
[Transaction(TransactionMode.Manual)]
|
||
internal class RevitAddin : ExternalCommand
|
||
{
|
||
public override void Execute()
|
||
{
|
||
//UiApplication.Application.DocumentOpening+= (s, e) =>
|
||
//{
|
||
// MessageBox.Show("DocumentOpening");
|
||
//};
|
||
//UiApplication.Application.FamilyLoadingIntoDocument += (s, e) =>
|
||
//{
|
||
// MessageBox.Show("FamilyLoadingIntoDocument");
|
||
//};
|
||
//UiApplication.Application.FamilyLoadedIntoDocument += (s, e) =>
|
||
//{
|
||
// MessageBox.Show("FamilyLoadedIntoDocument");
|
||
//};
|
||
//var ptr = ComponentManager.ApplicationWindow;
|
||
|
||
var win = GetWindowFromHwnd(Process.GetCurrentProcess().MainWindowHandle);
|
||
win?.Drop += (s, e) =>
|
||
{
|
||
MessageBox.Show("Drop");
|
||
};
|
||
//UIApplication.DoDragDrop(, new DropHandler());
|
||
|
||
return;
|
||
|
||
#if false
|
||
var refer = UiDocument.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element);
|
||
var wall = Document.GetElement(refer);
|
||
//var point = UiDocument.Selection.PickPoint(Autodesk.Revit.UI.Selection.ObjectSnapTypes.Nearest);
|
||
#endif
|
||
Array builtInCategories = Enum.GetValues(typeof(BuiltInCategory));
|
||
StringBuilder sb = new StringBuilder();
|
||
var encoding = Encoding.GetEncoding(936);
|
||
var str = File.ReadAllText(@"E:\Users\Zhanggg\Downloads\exportlayers-dwg-SZMEDI.txt", encoding);
|
||
foreach (BuiltInCategory cate in builtInCategories)
|
||
{
|
||
try
|
||
{
|
||
var name = Enum.GetName(typeof(BuiltInCategory), cate).Remove(0, 4);
|
||
var category = Document.Settings.Categories.get_Item(cate);
|
||
|
||
//var category = Category.GetCategory(Document, cate);
|
||
// 使用正则表达式进行全字匹配替换
|
||
str = Regex.Replace(
|
||
str,
|
||
$@"\b{Regex.Escape(name)}\b", // 自动处理特殊字符
|
||
category.Name,
|
||
RegexOptions.None); // 可选:是否区分大小写
|
||
|
||
//str = str.Replace(name, category.Name);
|
||
//if (category != null
|
||
// && category.CategoryType == CategoryType.FacilityNumber && category.AllowsBoundParameters)
|
||
//{
|
||
// sb.AppendLine($"{category.Name},{Enum.GetName(typeof(BuiltInCategory), cate)},");
|
||
//}
|
||
}
|
||
catch (Exception)
|
||
{
|
||
}
|
||
}
|
||
File.WriteAllText(@"E:\Users\Zhanggg\Downloads\exportlayers-dwg-SZMEDI-Result.txt", str, encoding);
|
||
|
||
//LogAssists.WriteTxtFile("内建类别", sb.ToString());
|
||
}
|
||
/// <summary>
|
||
/// 通过窗口句柄安全地获取WPF窗口对象
|
||
/// </summary>
|
||
/// <param name="hwnd">窗口句柄</param>
|
||
/// <returns>对应的WPF窗口对象,如果找不到则返回null</returns>
|
||
public static Window GetWindowFromHwnd(IntPtr hwnd)
|
||
{
|
||
try
|
||
{
|
||
// 从句柄获取HwndSource
|
||
var hwndSource = HwndSource.FromHwnd(hwnd);
|
||
if (hwndSource == null)
|
||
{
|
||
return null;
|
||
}
|
||
|
||
// 检查RootVisual是否为Window类型
|
||
if (hwndSource.RootVisual is DependencyObject rootVisual)
|
||
{
|
||
// 通过可视化树向上查找Window
|
||
DependencyObject current = rootVisual;
|
||
while (current != null)
|
||
{
|
||
if (current is Window window)
|
||
{
|
||
return window;
|
||
}
|
||
current = VisualTreeHelper.GetParent(current);
|
||
}
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
// 可以在此记录异常或进行其他处理
|
||
Console.WriteLine($"获取窗口失败: {ex.Message}");
|
||
}
|
||
|
||
return null;
|
||
}
|
||
private static void MoveElement(Element item, XYZ vector)
|
||
{
|
||
if (item.Pinned || !item.IsValidObject || item == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
var doc = item.Document;
|
||
var levels = doc.OfType<Level>().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.GetLocCurve().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.OfType<WallSweep>().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.OfType<FamilyInstance>().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);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 设置墙高度
|
||
/// </summary>
|
||
/// <param name="vector"></param>
|
||
/// <param name="levels"></param>
|
||
/// <param name="wall"></param>
|
||
private static void SetWallHeight(XYZ vector, List<Level> 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);
|
||
}
|
||
}
|
||
/// <summary>
|
||
/// 获取距离最近的标高
|
||
/// </summary>
|
||
/// <param name="levels"></param>
|
||
/// <param name="elev">高度</param>
|
||
/// <returns></returns>
|
||
private static Level GetClosetLevel(List<Level> levels, double elev)
|
||
{
|
||
return levels.First(l => Math.Abs(l.Elevation - elev) == levels.Min(l => Math.Abs(l.Elevation - elev)));
|
||
}
|
||
|
||
private void Application_DocumentChanged(object sender, Autodesk.Revit.DB.Events.DocumentChangedEventArgs e)
|
||
{
|
||
UiApplication.Application.DocumentChanged -= Application_DocumentChanged;
|
||
var sb = new StringBuilder();
|
||
|
||
var doc = e.GetDocument();
|
||
sb.AppendLine("删除的元素ID");
|
||
e.GetDeletedElementIds().ToList().ForEach(id => sb.AppendLine(id.IntegerValue.ToString()));
|
||
//Debug.WriteLine(e.GetDeletedElementIds().Count);
|
||
sb.AppendLine("修改的元素");
|
||
e.GetModifiedElementIds().Select(Document.GetElement).Where(e => e != null && e.Category != null && e.Category.CategoryType == CategoryType.Model && e.get_BoundingBox(null) != null).ToList().ForEach(e =>
|
||
{
|
||
sb.AppendLine(e?.Category.Name + "---------" + e?.Name);
|
||
});
|
||
File.WriteAllText(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "修改的元素.txt"), sb.ToString());
|
||
}
|
||
}
|
||
|
||
public class DropHandler : IControllableDropHandler
|
||
{
|
||
public bool CanExecute(UIDocument document, object data, ElementId dropViewId)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
|
||
public void Execute(UIDocument document, object data)
|
||
{
|
||
throw new NotImplementedException();
|
||
}
|
||
}
|
||
}
|