using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Text; using System.Text.RegularExpressions; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Architecture; using Autodesk.Revit.DB.Structure; using Autodesk.Revit.UI; using Nice3point.Revit.Toolkit.External; //using Szmedi.Toolkit.Assists; namespace Szmedi.Test { [Transaction(TransactionMode.Manual)] internal class RevitAddin : ExternalCommand { public override void Execute() { #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()); } private static void MoveElement(Element item, XYZ vector) { if (item.Pinned || !item.IsValidObject || item == null) { return; } var doc = item.Document; var levels = doc.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.GetLocCurve().CreateTransformed(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().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().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))); } 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()); } } }