using System.Diagnostics; using System.IO; using System.Text; using System.Windows; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Visual; using Autodesk.Revit.UI; using ShrlAlgoToolkit.Revit.Assists; using ShrlAlgoToolkit.Revit.Extensions; namespace ShrlAlgoToolkit.Revit.Assists; public static class DocumentAssist { /// /// 轴网标注 /// /// /// /// /// /// public static Dimension CreateDimensionByExtremeGrids( this Document doc, Line chainDimensionLine, ExtremeWallVariant extremeWallVariant, List grids ) { Dimension result; if (!grids.Any()) { result = null; } else { Dimension dimension = null; ReferenceArray referenceArray = new(); if (extremeWallVariant is ExtremeWallVariant.Left or ExtremeWallVariant.Right) { var list = ( from g in grids where ((Line)g.Curve).Direction.DotProduct(XYZ.BasisY) < 0.0001 select g ).ToList(); if (list.Any()) { list.Sort((g1, g2) => g1.Curve.GetEndPoint(0).Y.CompareTo(g2.Curve.GetEndPoint(0).Y)); List list2 = [list.First(), list.Last()]; foreach (var grid in list2) { referenceArray.Append(new Reference(grid)); } } } else { var list3 = ( from g in grids where ((Line)g.Curve).Direction.DotProduct(XYZ.BasisX) < 0.0001 select g ).ToList(); if (list3.Any()) { list3.Sort((g1, g2) => g1.Curve.GetEndPoint(0).X.CompareTo(g2.Curve.GetEndPoint(0).X)); List list4 = [list3.First(), list3.Last()]; foreach (var grid2 in list4) { referenceArray.Append(new Reference(grid2)); } } } if (!referenceArray.IsEmpty && referenceArray.Size > 1) { dimension = doc.Create.NewDimension(doc.ActiveView, chainDimensionLine, referenceArray); } result = dimension; } return result; } /// /// 获取所有可预览视图ID /// /// /// /// /// public static ElementId FindPreviewId(this Document doc, DocumentPreviewSettings setting) where T : View { var collector = new FilteredElementCollector(doc).OfClass(typeof(T)); if (!collector.Any()) { return new FilteredElementCollector(doc).OfClass(typeof(ViewPlan)).FirstElementId(); } var viewForPreview = collector.OfType().First(v => setting.IsViewIdValidForPreview(v.Id)); return viewForPreview.Id; } /// /// 获取标高范围框 /// /// 最低标高除了包含以上部分,还包含以下部分,最高标高包含以上部分 /// /// public static Dictionary GetLevelRanges(this Document doc) { var levels = doc.OfClass().Cast().OrderBy(l => l.Elevation).ToList(); Dictionary levelOutlines = []; //获取标高范围 for (var i = 0; i < levels.Count; i++) { var baseLevel = levels[i]; XYZ min = new(double.MinValue, double.MinValue, baseLevel.Elevation); XYZ max; Outline outline; if (i == 0) { min = new XYZ(double.MinValue, double.MinValue, double.MinValue); var topLevel = levels[i + 1]; max = new XYZ(double.MaxValue, double.MaxValue, topLevel.Elevation); outline = new Outline(min, max); } else if (i < levels.Count - 1) { var topLevel = levels[i + 1]; max = new XYZ(double.MaxValue, double.MaxValue, topLevel.Elevation); outline = new Outline(min, max); } else//最后一个标高以上 { max = new XYZ(double.MaxValue, double.MaxValue, double.MaxValue); outline = new Outline(min, max); } levelOutlines.Add(baseLevel, outline); } return levelOutlines; } public static Dimension CreateDimensionByOverallWalls( this Document doc, Line chainDimensionLine, IReadOnlyCollection sideWalls, ExtremeWallVariant extremeWallVariant ) { Dimension dimension = null; var list = sideWalls.Where(w => w.Orientation.DotProduct(XYZ.BasisX) < 0.0001).ToList(); var list2 = sideWalls.Where(w => w.Orientation.DotProduct(XYZ.BasisY) < 0.0001).ToList(); Dimension result; if (!list.Any() && !list2.Any()) { result = null; } else { ReferenceArray referenceArray = new(); if (extremeWallVariant is ExtremeWallVariant.Right or ExtremeWallVariant.Left) { List list3 = []; foreach (var wall in list) { foreach (var planarFace in wall.GetFaces()) { if (planarFace.IsHorizontal()) { list3.Add(planarFace); } } var elementArray = ((LocationCurve)wall.Location).get_ElementsAtJoin(0); var elementArray2 = ((LocationCurve)wall.Location).get_ElementsAtJoin(1); List list4 = []; foreach (Element element in elementArray) { var wallFromListById = (from w in list where w.Id == element.Id select w).First(); if (wallFromListById != null) { list4.Add(wallFromListById); } } foreach (Element element2 in elementArray2) { var wallFromListById2 = (from w in list where w.Id == element2.Id select w).First(); if (wallFromListById2 != null) { list4.Add(wallFromListById2); } } foreach (var wall2 in list4) { foreach (var planarFace2 in wall2.GetFaces()) { if (planarFace2.IsHorizontal()) { list3.Add(planarFace2); } } } } list3.Sort((f1, f2) => f1.GetMinY().CompareTo(f2.GetMinY())); referenceArray.Append(list3.First().Reference); referenceArray.Append(list3.Last().Reference); } if (extremeWallVariant is ExtremeWallVariant.Top or ExtremeWallVariant.Bottom) { List list5 = []; foreach (var wall3 in list2) { foreach (var planarFace3 in wall3.GetFaces()) { if (planarFace3.IsVertical()) { list5.Add(planarFace3); } } var elementArray3 = ((LocationCurve)wall3.Location).get_ElementsAtJoin(0); var elementArray4 = ((LocationCurve)wall3.Location).get_ElementsAtJoin(1); List list6 = []; foreach (Element element3 in elementArray3) { var wallFromListById3 = (from w in list where w.Id == element3.Id select w).First(); if (wallFromListById3 != null) { list6.Add(wallFromListById3); } } foreach (Element element4 in elementArray4) { var wallFromListById4 = (from w in list where w.Id == element4.Id select w).First(); if (wallFromListById4 != null) { list6.Add(wallFromListById4); } } foreach (var wall4 in list6) { foreach (var planarFace4 in wall4.GetFaces()) { var isVertical2 = planarFace4.IsVertical(); if (isVertical2) { list5.Add(planarFace4); } } } } list5.Sort((f1, f2) => f1.GetMinX().CompareTo(f2.GetMinX())); referenceArray.Append(list5[0].Reference); referenceArray.Append(list5.Last().Reference); } if (!referenceArray.IsEmpty) { doc.Invoke(_ => { dimension = doc.Create.NewDimension(doc.ActiveView, chainDimensionLine, referenceArray); }); } result = dimension; } return result; } /// /// 创建房间 /// /// /// /// public static void CreateRoom(this Document doc, Level level, Phase phase) { // 获取基于标高level的一个视图 var defaultView = new FilteredElementCollector(doc) .OfClass(typeof(View)) .Cast() .FirstOrDefault(v => v.GenLevel != null && v.GenLevel.Id == level.Id); // 确保视图不为空 if (defaultView != null) { var defaultPhase = defaultView.get_Parameter(BuiltInParameter.VIEW_PHASE); if (defaultPhase != null && defaultPhase.AsElementId() == phase.Id) { var circuits = doc.get_PlanTopology(level, phase).Circuits; foreach (PlanCircuit planCircuit in circuits) { doc.Create.NewRoom(null, planCircuit); } } } } /// /// 创建表格 /// /// /// /// /// /// /// public static void CreateTable( this Document doc, View legend, int rowCount, int columnCount, double gridWidth, double gridHeight ) { CurveArray curveArray = new(); for (var i = 0; i <= rowCount; i++) //水平网格 { var l = Line.CreateBound(XYZ.Zero, XYZ.BasisX * gridWidth * columnCount) .CreateOffset(gridHeight * i, -XYZ.BasisZ); curveArray.Append(l); } Curve line = Line.CreateBound(XYZ.Zero, XYZ.BasisY * rowCount * gridHeight); curveArray.Append(line); for (var i = 0; i <= columnCount; i++) //垂直网格 { line = line.CreateOffset(gridWidth, XYZ.BasisZ); curveArray.Append(line); } doc.Create.NewDetailCurveArray(legend, curveArray); } /// /// 创建表格 /// /// /// 图例视图 /// 行数 /// 列数 /// 单元格高度 /// 各列对应的宽度 public static void CreateTable( this Document doc, View legend, int rowCount, int columnCount, double gridHeight, params double[] gridWidths ) { if (columnCount != gridWidths.Length) { return; } CurveArray curveArray = new(); var totalWidth = 0.0; foreach (var w in gridWidths) { totalWidth += w; } for (var i = 0; i <= rowCount; i++) //水平网格 { var c = Line.CreateBound(XYZ.Zero, XYZ.BasisX * totalWidth).CreateOffset(gridHeight * i, -XYZ.BasisZ); curveArray.Append(c); } Curve line = Line.CreateBound(XYZ.Zero, XYZ.BasisY * rowCount * gridHeight); curveArray.Append(line); for (var i = 0; i < columnCount; i++) //垂直网格 { line = line.CreateOffset(gridWidths[i], XYZ.BasisZ); curveArray.Append(line); } doc.Create.NewDetailCurveArray(legend, curveArray); } /// /// 创建表格 /// /// 图例视图 /// 行数(含标题行) /// 列数 /// /// 单元格高度 /// 各单元格对应的宽度 public static void CreateTable( View legend, int rowCount, int columnCount, double headHeight, double gridHeight, params double[] gridWidths ) { var doc = legend.Document; if (columnCount != gridWidths.Length) { MessageBox.Show("列数和提供的列宽数量不一致。", "提示"); return; } CurveArray curveArray = new(); var totalWidth = 0.0; foreach (var w in gridWidths) { totalWidth += w; } for (var i = 0; i <= rowCount - 1; i++) //水平网格 { var c = Line.CreateBound(XYZ.Zero, XYZ.BasisX * totalWidth).CreateOffset(gridHeight * i, -XYZ.BasisZ); curveArray.Append(c); } //标题行 var line = Line.CreateBound(XYZ.Zero, XYZ.BasisX * totalWidth) .CreateOffset((gridHeight * (rowCount - 1)) + headHeight, -XYZ.BasisZ); curveArray.Append(line); //列 line = Line.CreateBound(XYZ.Zero, XYZ.BasisY * (((rowCount - 1) * gridHeight) + headHeight)); curveArray.Append(line); for (var i = 0; i < columnCount; i++) //垂直网格 { line = line.CreateOffset(gridWidths[i], XYZ.BasisZ); curveArray.Append(line); } doc.Create.NewDetailCurveArray(legend, curveArray); } public static void CreateTag(this Document doc, List references, TagMode tagMode, bool hasLeader) { foreach (var refer in references) { try { IndependentTag.Create( doc, doc.ActiveView.Id, refer, hasLeader, tagMode, TagOrientation.Horizontal, new XYZ(0, 0, 0) ); } catch { // ignored } } } public static void DeleteFamilyType(this Document famdoc) { // 得到FamilyManager var familyMgr = famdoc.FamilyManager; if (familyMgr.CurrentType != null) { // 只有当前族类型存在,我们才能调用下面的删除方法 familyMgr.DeleteCurrentType(); // 一般来说,当删除结束后,第一个族类型会成为当前类型, // 但是为了确保安全, 建议你显式设置成你需要的类型 if (familyMgr.Types.Size != 0) { var type = familyMgr.Types.Cast().ElementAt(0); familyMgr.CurrentType = type; } } } /// /// 删除定位点重合的族实例 /// /// /// public static void DeleteOverlapInstance(this Document doc, List cardInstances) { List idsToDelete = []; foreach (var ins in cardInstances) { var lp = ins.GetLocXYZ(); foreach (var card in cardInstances) { var lpt = card.GetLocXYZ(); if (!card.Id.Equals(ins.Id) && lp.IsAlmostEqualTo(lpt)) { idsToDelete.Add(ins.Id); idsToDelete.Add(card.Id); break; } } } doc.Delete(idsToDelete); } /// /// 复制图例 /// /// /// /// 比例 /// public static View DuplicateLegend(Document doc, string legendName, int viewScale) { var legends = doc.OfClass() .OfCategory(BuiltInCategory.OST_Views) .Cast() .Where(v => v.ViewType == ViewType.Legend) .ToList(); if (!legends.Any()) { MessageBox.Show("当前项目中没有图例", "温馨提示"); return null; } var legendToCopy = legends.FirstOrDefault(); var newLegendId = legendToCopy?.Duplicate(ViewDuplicateOption.Duplicate); var newLegend = doc.GetElement(newLegendId) as View; for (var i = 0; i < 100; i++) { try { newLegend!.Name = $"{legendName} {i}"; break; } catch (Autodesk.Revit.Exceptions.ArgumentException) { } } newLegend!.Scale = viewScale; return newLegend; } /// /// 翻转工作平面 /// /// /// public static void FlipWorkPlane(this Document doc, ElementId id) { var fi = (FamilyInstance)doc.GetElement(id); if (fi != null) { fi.IsWorkPlaneFlipped = !fi.IsWorkPlaneFlipped; } } public static FamilySymbol GetAndActiveDefaultFamilySymbol(this Document doc, string rfaFile) { var family = GetOrLoadedFamily(doc, rfaFile); FamilySymbol symbol = null; if (family != null) { var symbolId = family.GetFamilySymbolIds().FirstOrDefault(); symbol = doc.GetElement(symbolId) as FamilySymbol; Debug.Assert(symbol != null, nameof(symbol) + " != null"); if (!symbol.IsActive) { symbol.Activate(); } } return symbol; } /// /// 获取族中的元素 /// /// /// public static List GetFamilySolidForm(this Document famdoc) { var ids = new List(); if (famdoc.IsFamilyDocument) { var solids = new FilteredElementCollector(famdoc) .OfClass(typeof(GenericForm)) .Cast() .Where(x => x.IsSolid) .Select(y => y.Id); var fiids = new FilteredElementCollector(famdoc).OfClass(typeof(FamilyInstance)).Select(y => y.Id); ids.AddRange(solids); ids.AddRange(fiids); } return ids; } /// /// 填充样式 /// /// /// /// public static ElementId GetFillPatternElemId(this Document doc, string patternName) { var fillPatternElemId = ElementId.InvalidElementId; var fecOfFpe = new FilteredElementCollector(doc).OfClass(typeof(FillPatternElement)); foreach (var element in fecOfFpe.ToElements()) { var fpe = element as FillPatternElement; var fp = fpe.GetFillPattern(); if (null != fp && fp.Name == patternName) { fillPatternElemId = fpe.Id; break; } } return fillPatternElemId; } /// /// 获取已载入同名族,若无,则载入 /// /// /// /// public static Family GetOrLoadedFamily(this Document doc, string familyPath) { var family = new FilteredElementCollector(doc) .OfClass(typeof(Family)) .Cast() .FirstOrDefault(f => f.Name == Path.GetFileNameWithoutExtension(familyPath)); if (family == null && File.Exists(familyPath)) { doc.LoadFamily(familyPath, new DefaultFamilyLoadOptions(), out family); } return family; } /// /// 获取或创建文字类型 /// /// /// 文字类型名称 /// /// /// /// public static TextNoteType GetOrNewTextNoteType( this Document doc, string textSymbolName, string fontFamily, string fontSize, string widthScale ) { var textNoteType = new FilteredElementCollector(doc) .OfClass(typeof(TextNoteType)) .OfType() .FirstOrDefault(x => x.Name.Contains(textSymbolName)); if (textNoteType != null) { return textNoteType; } textNoteType = new FilteredElementCollector(doc) .OfClass(typeof(TextNoteType)) .Cast() .FirstOrDefault() ?.Duplicate(textSymbolName) as TextNoteType; if (textNoteType != null) { textNoteType.get_Parameter(BuiltInParameter.TEXT_FONT).SetValueString(fontFamily); textNoteType.get_Parameter(BuiltInParameter.TEXT_SIZE).SetValueString(fontSize); textNoteType.get_Parameter(BuiltInParameter.TEXT_WIDTH_SCALE).SetValueString(widthScale); } return textNoteType; } /// /// 射线法获取参照 /// /// /// public static Reference GetSpotDimensionReference(this Document doc, XYZ vector) { Reference reference = null; if (doc.ActiveView is ViewPlan view) { //可能存在贯穿标高的构件,需修改射线贯穿距离 #region 视图范围 var range = view.GetViewRange(); var bottomLevel = doc.GetElement(range.GetLevelId(PlanViewPlane.BottomClipPlane)) as Level; var b = range.GetOffset(PlanViewPlane.BottomClipPlane); var topLevel = doc.GetElement(range.GetLevelId(PlanViewPlane.TopClipPlane)) as Level; var t = range.GetOffset(PlanViewPlane.TopClipPlane); var bot = bottomLevel.Elevation + b; var tt = topLevel.Elevation + t; var p1 = new XYZ(vector.X, vector.Y, bot); var p2 = new XYZ(vector.X, vector.Y, tt); #endregion 视图范围 var v3d = new FilteredElementCollector(doc) .OfClass(typeof(View3D)) .Cast() .FirstOrDefault(v => !v.IsTemplate); //射线法找到相交的元素 ReferenceIntersector intersector = new(v3d); var refer = intersector.FindNearest(p1, XYZ.BasisZ)?.GetReference(); var refer1 = intersector.FindNearest(p2, -XYZ.BasisZ)?.GetReference(); if (refer != null && refer1 != null) { reference = refer.GlobalPoint.Z > refer1.GlobalPoint.Z ? refer : refer1; } } return reference; //Line l2 = Line.CreateUnbound(vector, XYZ.BasisZ); } /// /// dwg图层隐藏 /// /// /// 选择的dwg引用,PointOnElement /// /// public static void HideDwgLayer( this Document doc, Reference reference, out ElementId graphicStyleId, out GeometryElement geoElem ) { var dwg = doc.GetElement(reference) as ImportInstance; graphicStyleId = null; Options opts = new() { ComputeReferences = true, IncludeNonVisibleObjects = true, DetailLevel = 0 }; geoElem = dwg?.get_Geometry(opts); var geoObj = dwg?.GetGeometryObjectFromReference(reference); if ( geoObj != null && geoObj.GraphicsStyleId != ElementId.InvalidElementId && doc.GetElement(geoObj.GraphicsStyleId) is GraphicsStyle gsSelected ) { //图层Id graphicStyleId = gsSelected.GraphicsStyleCategory.Id; doc.Invoke( _ => { doc.ActiveView.SetCategoryHidden(gsSelected.GraphicsStyleCategory.Id, true); }, "隐藏图层" ); } } /// /// 链接cad /// /// /// public static void LinkDwgByPaths(this Document doc, params string[] linkPaths) { if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (linkPaths is null) { throw new ArgumentNullException(nameof(linkPaths)); } var options = new DWGImportOptions { OrientToView = true }; //var li = linkPaths.ToList(); //li.ForEach(famdoc.Link(linkPath, options, famdoc.ActiveView, out _)); foreach (var linkPath in linkPaths) { doc.Link(linkPath, options, doc.ActiveView, out _); } } /// /// 链接Revit /// /// /// /// public static void LinkRvt(this Document doc, params string[] linkPaths) { if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (linkPaths is null) { throw new ArgumentNullException(nameof(linkPaths)); } foreach (var linkPath in linkPaths) { var filePath = new FilePath(linkPath); var linkOption = new RevitLinkOptions(false); var result = RevitLinkType.Create(doc, filePath, linkOption); var instance = RevitLinkInstance.Create(doc, result.ElementId); if (doc.GetElement(instance.GetTypeId()) is not RevitLinkType type) { return; } type.AttachmentType = AttachmentType.Attachment; type.PathType = PathType.Relative; } } public static void ReadImporterFile( this Document revitDoc, ShapeImporterSourceFormat sourceFormat, BuiltInCategory builtInCategory ) { //ofd.Filter = "SAT Files (.sat)|.sat"; FileOpenDialog ofd = new("*"); if (ofd.Show() == ItemSelectionDialogResult.Confirmed) { ShapeImporter shapeImporter = new() { InputFormat = sourceFormat }; var mp = ofd.GetSelectedModelPath(); var fileName = ModelPathUtils.ConvertModelPathToUserVisiblePath(mp); var shapes = shapeImporter.Convert(revitDoc, fileName); if (shapes.Count != 0) { using Transaction tr = new(revitDoc, "创建内建模型"); tr.Start(); var dsImportedSat = DirectShape.CreateElement(revitDoc, new ElementId(builtInCategory)); dsImportedSat.SetShape(shapes); tr.Commit(); } } } /// /// 有类型定义的DirectShape /// /// /// 定义名称,即是族名称、类型名称(强制一致),创建多个实例时,如果相同,则会合并在一个族中 /// 族类别 /// 几何 /// 位置 /// public static DirectShape CreateDirectShapeInstance(this Document doc, string definitionId, BuiltInCategory category, List geos) { DirectShapeLibrary directShapeLibrary = DirectShapeLibrary.GetDirectShapeLibrary(doc); ElementId directShapeTypeId = directShapeLibrary.FindDefinitionType(definitionId); if (doc.GetElement(directShapeTypeId) == null) { var directShapeType = DirectShapeType.Create(doc, definitionId, new ElementId(category)); directShapeTypeId = directShapeType.Id; directShapeLibrary.AddDefinitionType(definitionId, directShapeTypeId); } //else //{ // directShapeLibrary.AddDefinition(definitionId, geos); //} var shape = DirectShape.CreateElementInstance(doc, directShapeTypeId, new ElementId(category), definitionId, Transform.Identity); //shape.SetTypeId(directShapeTypeId); //shape.SetName();实例名称 shape.SetShape(geos); return shape; } /// /// 无名称定义的DirectShape /// /// /// /// /// public static DirectShape CreateDirectShape(this Document doc, List geos, BuiltInCategory category) { var shape = DirectShape.CreateElement(doc, new ElementId(category)); shape.SetShape(geos); return shape; } /// /// 删除Revit链接 /// /// /// /// public static void RemoveLinks(this Document doc, params string[] linkPaths) { if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (linkPaths is null) { throw new ArgumentNullException(nameof(linkPaths)); } foreach (var linkPath in linkPaths) { var links = new FilteredElementCollector(doc).OfClass(typeof(RevitLinkInstance)); foreach (var link in links) { if (link.Name.Split(':').Length != 3) { continue; } if (link is not RevitLinkInstance instance) { continue; } if (link.Name == Path.GetFileName(linkPath)) { var type = doc.GetElement(instance.GetTypeId()) as RevitLinkType; type?.Unload(null); doc.Invoke(_ => { doc.Delete(instance.Id); }); } } } } public static void RenameFamilyType(this Document famdoc, string oldTypeName, string newTypeName) { if (famdoc.IsFamilyDocument) { // 得到FamilyManager var familyMgr = famdoc.FamilyManager; // 族类型的名字,保证在所有族类型中唯一 var isExist = false; foreach (FamilyType t in familyMgr.Types) { if (t.Name == oldTypeName) { familyMgr.CurrentType = t; familyMgr.RenameCurrentType(newTypeName); isExist = true; } } if (!isExist) { familyMgr.NewType(newTypeName); } } else { var familySymbol = new FilteredElementCollector(famdoc) .WhereElementIsElementType() .FirstOrDefault(t => t.Name == oldTypeName); if (familySymbol != null) { familySymbol.Name = newTypeName; } } } /// /// 设置中心文件 /// /// /// /// public static void SetCentralFile(this Document doc, string centralPath) { if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (centralPath is null) { throw new ArgumentNullException(nameof(centralPath)); } var saveOption = new SaveAsOptions { OverwriteExistingFile = true }; var sharingOption = new WorksharingSaveAsOptions { SaveAsCentral = true, OpenWorksetsDefault = SimpleWorksetConfiguration.LastViewed }; saveOption.SetWorksharingOptions(sharingOption); doc.SaveAs(centralPath, saveOption); } /// /// 设置Revit链接集合 /// /// /// public static void SetLinkList(string centralPath, List linkPaths) { if (centralPath is null) { throw new ArgumentNullException(nameof(centralPath)); } if (linkPaths is null) { throw new ArgumentNullException(nameof(linkPaths)); } var transData = TransmissionData.ReadTransmissionData(new FilePath(centralPath)); if (transData is null) { return; } // If found not the link, don't submit, otherwise throw file writing exception. var flag = false; foreach (var referId in transData.GetAllExternalFileReferenceIds()) { var extRef = transData.GetLastSavedReferenceData(referId); if (extRef.ExternalFileReferenceType != ExternalFileReferenceType.RevitLink) { continue; } var userPath = ModelPathUtils.ConvertModelPathToUserVisiblePath(extRef.GetPath()); var linkPath = linkPaths.FirstOrDefault(w => w != null && userPath.Contains(Path.GetFileName(w))); if (linkPath is null) { continue; } var elmId = extRef.GetReferencingId(); transData.SetDesiredReferenceData(elmId, new FilePath(linkPath), PathType.Relative, true); flag = true; } if (!flag) { return; } transData.IsTransmitted = true; TransmissionData.WriteTransmissionData(new FilePath(centralPath), transData); } /// /// 设置Revit链接 /// /// /// public static void SetLinks(this Document doc, params string[] filePaths) { if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (filePaths is null) { throw new ArgumentNullException(nameof(filePaths)); } foreach (var filePath in filePaths) { if (!File.Exists(filePath)) { throw new FileNotFoundException(filePath); } // main elementFunc modifies repeatedly, so the performance is poor. var linkTypes = doc.OfClass().Where(w => filePath.Contains(w.Name)); if (linkTypes.FirstOrDefault(f => f.Name.Split('-').Length == 5) is not RevitLinkType type) { return; } type.LoadFrom(new FilePath(filePath), new WorksetConfiguration(WorksetConfigurationOption.OpenLastViewed)); type.PathType = PathType.Relative; } } /// /// 移除0长度标注 /// /// /// /// public static bool TryRemoveZeroes(this Dimension dimension, out ReferenceArray referenceArray) { referenceArray = new ReferenceArray(); var document = dimension.Document; var isEmpty = dimension.Segments.IsEmpty; if (isEmpty) { return false; } else { for (var i = 0; i < dimension.NumberOfSegments; i++) { var dimensionSegment = dimension.Segments.get_Item(i); var value = dimensionSegment.Value; if (!(value != null && Math.Abs(value.Value) < 0.0001)) { var isEmpty2 = referenceArray.IsEmpty; if (isEmpty2) { var refer = dimension.References.get_Item(i); var element = document.GetElement(refer); if (element is Grid or Level) { refer = new Reference(element); } referenceArray.Append(refer); } var refer1 = dimension.References.get_Item(i + 1); var element1 = document.GetElement(refer1); if (element1 is Grid or Level) { refer1 = new Reference(element1); } referenceArray.Append(refer1); } } return referenceArray.Size < dimension.References.Size; } } /// /// 隐藏或者显示图层 /// /// /// /// tr是显示 false是隐藏 public static void VisLayer(this Document doc, Reference reference, bool bl) { var element = doc.GetElement(reference); //GeometryElement geoElem = elementFunc.get_Geometry(new Options()); //几何图元 var geoObj = element.GetGeometryObjectFromReference(reference); //几何对象 if (geoObj.GraphicsStyleId != ElementId.InvalidElementId) { if (doc.GetElement(geoObj.GraphicsStyleId) is GraphicsStyle gs) { var targetCategory = gs.GraphicsStyleCategory; doc.ActiveView.SetCategoryHidden(targetCategory.Id, bl); } } } /// /// 发光材质 /// /// public static void GetIllumMaterial(this Document doc) { var materials = doc.OfClass().Cast(); StringBuilder sb = new(); foreach (var material in materials) { if (doc.GetElement(material.AppearanceAssetId) is AppearanceAssetElement assetElem) { var asset = assetElem.GetRenderingAsset(); var prop = asset.FindByName("generic_self_illum_luminance"); var d = prop as AssetPropertyDouble; if (d?.Value > 0) { sb.AppendLine(material.Name); } } } } /// /// 射线法查找所有的Element /// /// Dcument /// 例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray)) /// 目标对象 /// 射源 /// 方向 /// 返回该射线 public static IList XRayFindAll( this Document doc, ElementFilter filter, FindReferenceTarget targetRef, XYZ center, XYZ direction ) { var view3D = doc.OfClass().Cast().First(v3 => !v3.IsTemplate); var refWithContexts = new ReferenceIntersector(filter, targetRef, view3D).Find(center, direction); if (refWithContexts == null) { return null; } var resultElements = new List(); foreach (var rwc in refWithContexts) { var reference = rwc.GetReference(); var hitElement = doc.GetElement(reference); if (hitElement != null) { resultElements.Add(hitElement); } } return resultElements; } /// /// 射线法查找最近的Element /// /// /// 例如:ElementClassFilter filter = new ElementClassFilter(typeof(CableTray)) /// 目标对象 /// 射源 /// 方向 /// 被击中的Element /// 返回该射线 public static Line XRayFindNearest( this Document doc, ElementFilter filter, FindReferenceTarget targetRef, XYZ center, XYZ direction, ref Element hitElement ) { var view3D = doc .OfClass() .Cast() .First(v3 => !v3.IsTemplate); ReferenceIntersector refIntersector = new(filter, targetRef, view3D); var rwc = refIntersector.FindNearest(center, direction); if (rwc == null) { return null; } var reference = rwc.GetReference(); var intersection = reference.GlobalPoint; hitElement = doc.GetElement(reference); Line result = null; if (!center.IsAlmostEqualTo(intersection)) { result = Line.CreateBound(center, intersection); } else { hitElement = null; } return result; } #if REVIT2021 /// /// 修改测量点 /// /// public static void ResetBasePoint(this Document doc) { var surveyPoint = BasePoint.GetSurveyPoint(doc); var pos = surveyPoint.Position; var sharedPos = surveyPoint.SharedPosition; //surveyPoint.Position.Subtract(pos); var projectBasePoint = BasePoint.GetProjectBasePoint(doc); var pos1 = projectBasePoint.Position; var sharePos1 = projectBasePoint.SharedPosition; using (Transaction trans = new(doc, "移动测量点")) { trans.Start(); ElementTransformUtils.MoveElement(doc, surveyPoint.Id, sharedPos.Negate()); doc.Regenerate(); ElementTransformUtils.MoveElement(doc, surveyPoint.Id, pos.Negate()); ElementTransformUtils.MoveElement(doc, projectBasePoint.Id, pos1.Negate()); projectBasePoint.get_Parameter(BuiltInParameter.BASEPOINT_ANGLETON_PARAM).Set(0); trans.Commit(); } if ( !( surveyPoint.SharedPosition.IsAlmostEqualTo(XYZ.Zero) && projectBasePoint.SharedPosition.IsAlmostEqualTo(XYZ.Zero) ) ) { MessageBox.Show("请修改测量点的裁剪状态", "提示", MessageBoxButton.OK, MessageBoxImage.Information); } } #endif }