功能更新

This commit is contained in:
GG Z
2026-02-23 11:21:51 +08:00
parent 3650f8550e
commit 6beb8b5be9
24 changed files with 694 additions and 1975 deletions

View File

@@ -29,34 +29,6 @@ namespace Szmedi.Test
{
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);
@@ -91,318 +63,6 @@ namespace Szmedi.Test
//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();
}
}
}