using System.Windows; using Autodesk.Revit.DB; using Autodesk.Revit.UI; namespace ShrlAlgo.Toolkit.Revit.Assist; /// SectionView: /// RightDirection = CropBox.Transform.BasisX; /// ViewDirection = CropBox.Transform.BasisZ; /// UpDirection = XYZ.BasisZ =CropBox.Transform.BasisY public static class ViewAssist { /// /// 复制视图 /// /// /// /// /// public static View CopyWithOption(this View view, ViewDuplicateOption option, string viewName = default) { if (view.CanViewBeDuplicated(option)) { var eleId = view.Duplicate(option); var viewCopy = view.Document.GetElement(eleId) as View; if (viewName != default) { try { viewCopy.Name = viewName; } catch (Autodesk.Revit.Exceptions.ArgumentException) { } } return viewCopy; } return null; } /// /// 获取多个元素的包围框 /// /// /// /// /// /// /// public static BoundingBoxXYZ GetElementsBox(this View view, List elementIds, int extendXyz = 1) { if (view == null) { throw new ArgumentNullException(nameof(view), "视图为空"); } var doc = view.Document; if (elementIds == null || elementIds.Any()) { return null; } var f = doc.GetElement( elementIds.FirstOrDefault(elem => doc.GetElement(elem).get_BoundingBox(view) != null) ); var b = f.get_BoundingBox(view); var maxX = b.Max.X; var maxY = b.Max.Y; var maxZ = b.Max.Z; var minX = b.Min.X; var minY = b.Min.Y; var minZ = b.Min.Z; foreach (var elementId in elementIds) { var e = doc.GetElement(elementId); var bb = e.get_BoundingBox(view); if (b == null)//?莫名其妙等于空 { continue; } if (bb.Max.X >= maxX) { maxX = bb.Max.X; } if (bb.Max.Y >= maxY) { maxY = bb.Max.Y; } if (bb.Max.Z >= maxZ) { maxZ = bb.Max.Z; } if (bb.Min.X <= minX) { minX = bb.Min.X; } if (bb.Min.Y <= minY) { minY = bb.Min.Y; } if (bb.Min.Z <= minZ) { minZ = bb.Min.Z; } } var box = b.Extend(extendXyz); //var max = new XYZ(maxX, maxY, maxZ) + b.Max.Normalize() * extendXyz; //var min = new XYZ(minX, minY, minZ) - b.Min.Normalize() * extendXyz; //b.Max = max; //b.Min = min; return box; } /// /// 获取元素的包围框 /// /// /// /// /// /// /// public static BoundingBoxXYZ GetElementBox(this View view, ElementId elementId, int extendXyz = 1) { if (view == null) { throw new ArgumentNullException(nameof(view), "视图为空"); } var doc = view.Document; var e = doc.GetElement(elementId); if (!e.IsValidObject) { throw new InvalidOperationException("元素无效"); } var b = e.get_BoundingBox(view); if (b == null)//?莫名其妙等于空 { return null; } var box = b.Extend(extendXyz); return box; } /// /// 恢复替换的外观 /// /// /// public static void ResetOverrideAppearance(this View view, List elements) { OverrideGraphicSettings overrideGraphicSettings = new(); foreach (var panel in elements) { view.SetElementOverrides(panel.Id, overrideGraphicSettings); } } /// /// 新建视图并设置剖切框,若无法剖切则返回用于复制的三维视图 /// /// 用于复制的三维视图 /// /// 是否在当前视图创建 /// /// public static View3D SectionBoxElement(this View3D view3D, ElementId elementId, bool inCurrentView = true, int extendXYZ = 1) { var b = view3D.GetElementBox(elementId, extendXYZ); if (b == null) { return view3D; } if (!view3D.IsSectionBoxActive) { view3D.IsSectionBoxActive = true; } if (inCurrentView) { view3D.SetSectionBox(b); return view3D; } var viewCopyId = view3D.Duplicate(ViewDuplicateOption.WithDetailing); var viewCopy = view3D.Document.GetElement(viewCopyId) as View3D; viewCopy.DisplayStyle = DisplayStyle.ShadingWithEdges; viewCopy.DetailLevel = ViewDetailLevel.Fine; viewCopy?.SetSectionBox(b); return viewCopy; } /// /// 新建视图并设置剖切框,若无法剖切则返回用于复制的三维视图 /// /// 用于复制的三维视图 /// /// 是否在当前视图创建 /// /// public static View3D SectionBoxElements(this View3D view3D, List elementIds, bool inCurrentView = true, int extendXYZ = 1) { var b = view3D.GetElementsBox(elementIds, extendXYZ); if (b == null) { return view3D; } if (!view3D.IsSectionBoxActive) { view3D.IsSectionBoxActive = true; } if (inCurrentView) { view3D.SetSectionBox(b); return view3D; } var viewCopyId = view3D.Duplicate(ViewDuplicateOption.WithDetailing); var viewCopy = view3D.Document.GetElement(viewCopyId) as View3D; viewCopy.DisplayStyle = DisplayStyle.ShadingWithEdges; viewCopy.DetailLevel = ViewDetailLevel.Fine; viewCopy?.SetSectionBox(b); return viewCopy; } /// /// 设置图例位置 /// /// /// public static void SetLegendLocation(this View legend, XYZ location) { var doc = legend.Document; var viewport = Viewport.Create(doc, doc.ActiveView.Id, legend.Id, XYZ.Zero); if (viewport == null) { MessageBox.Show("视图中可能未包含图例所需的元素,请选择\r正确的图纸视口或图例命令来创建图例。", "温馨提示"); return; } var outline = viewport.GetBoxOutline(); var l = outline.MaximumPoint.X - outline.MinimumPoint.X; var w = outline.MaximumPoint.Y - outline.MinimumPoint.Y; var c = new XYZ(l / 2, w / 2, 0) + location; viewport.SetBoxCenter(c); var ele = doc.OfClass().FirstOrDefault(x => x.Name.Contains("无标题")); viewport.ChangeTypeId(ele?.Id); //选择视口-无标题 } /// /// 已经打开的视图中缩放视图,最大化图元 /// /// /// /// /// 扩宽范围 public static void ZoomElements(this View view, UIDocument uidoc, List elementIds, int extend = 2) { var box = view.GetElementsBox(elementIds, extend); if (box == null) return; var uiView = uidoc.GetOpenUIViews().FirstOrDefault(v => v.ViewId == uidoc.ActiveGraphicalView.Id); uiView?.ZoomAndCenterRectangle(box.Min, box.Max); } /// /// 已经打开的视图中缩放视图,最大化图元 /// /// /// /// /// 扩宽范围 public static void ZoomElement(this View view, UIDocument uidoc, ElementId elementId, int extend = 2) { var elem = uidoc.Document.GetElement(elementId); if (!elem.IsValidObject || !elem.IsVisible(view)) return; var box = elem.get_BoundingBox(view); if (box == null) return; box = box.Extend(extend); var uiView = uidoc.GetOpenUIViews().FirstOrDefault(v => v.ViewId == uidoc.ActiveGraphicalView.Id); uiView?.ZoomAndCenterRectangle(box.Min, box.Max); } #if REVIT2018 /// /// /// /// /// /// 需要跟过滤规则对应,否则无效 public static void CreateViewFilter( this View view, string viewFilterName, List rules, ISet categoryIds ) { var doc = view.Document; try { if (ParameterFilterElement.AllRuleParametersApplicable(doc, categoryIds, rules)) { var filter = ParameterFilterElement.Create(doc, viewFilterName, categoryIds); if (filter.AllRuleParametersApplicable(rules)) { filter.SetRules(rules); } view.AddFilter(filter.Id); var settings = view.GetFilterOverrides(filter.Id); //view.SetCutLineColor(new SelectedColor(255, 0, 0)); settings.SetProjectionLineColor(new Color(255, 0, 0)); view.SetFilterOverrides(filter.Id, settings); } } catch (Exception e) { MessageBox.Show(e.Message); } } #else /// /// /// /// /// /// 需要跟过滤规则对应,否则无效 /// public static void CreateViewFilter( this View view, string viewFilterName, ElementLogicalFilter logicalFilter, ISet categoryIds, params ElementParameterFilter[] paramFilters ) { var doc = view.Document; List filters = new(); foreach (var filter in paramFilters) { filters.Add(filter); } logicalFilter.SetFilters(filters); try { if ( ParameterFilterElement.ElementFilterIsAcceptableForParameterFilterElement( doc, categoryIds, logicalFilter ) ) { var filter = ParameterFilterElement.Create(doc, viewFilterName, categoryIds); if (filter.AllRuleParametersApplicable(logicalFilter)) { filter.SetElementFilter(logicalFilter); } view.AddFilter(filter.Id); var settings = view.GetFilterOverrides(filter.Id); //view.SetCutLineColor(new SelectedColor(255, 0, 0)); settings.SetProjectionLineColor(new Color(255, 0, 0)); view.SetFilterOverrides(filter.Id, settings); } } catch (Exception e) { MessageBox.Show(e.Message); e.StackTrace.ToLog(); } } #endif }