using System.Collections.ObjectModel; using System.Diagnostics; using System.Security.Cryptography; using System.Windows; using Autodesk.Revit.DB; using Autodesk.Revit.UI; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Input; using Nice3point.Revit.Toolkit.External.Handlers; namespace Sai.RvKits.RvView { public partial class QuickViewSectionViewModel : ObservableObject { private readonly ActionEventHandler handler = new(); [ObservableProperty] private bool isParallel = true; private readonly List viewSections = []; [RelayCommand] private void DeleteViewSection() { handler.Raise( uiapp => { var uidoc = uiapp.ActiveUIDocument; var doc = uidoc.Document; doc.Invoke( ts => { for (var i = viewSections.Count - 1; i >= 0; i--) { var view = viewSections[i]; if (view.IsValidObject) { var uiView = uidoc.GetOpenUIViews().FirstOrDefault(ui => ui.ViewId == view.Id); uiView?.Close(); viewSections.Remove(view); doc.Delete(view.Id); } } }, "删除快速剖面"); }); } [RelayCommand] private void CreateViewSection() { handler.Raise( uiapp => { var uidoc = uiapp.ActiveUIDocument; var element = uidoc.SelectObject(new FuncFilter(elem => elem.GetLocCurve() is Line)); #region 选择方向 //var firstTip = "请选择第一个点以确定正交剖面的定位点"; //var lastTip = "请选择第二个点以确定拉抻的深度"; //if (IsParallel) //{ // firstTip = "请选择第一个剖面范围水平的边界点"; // lastTip = "请选择第二个剖面范围水平的边界点"; //} //var firstrefer = uidoc.Selection // .PickObject(Autodesk.Revit.UI.Selection.ObjectType.PointOnElement, firstTip); //var lastrefer = uidoc.Selection // .PickObject(Autodesk.Revit.UI.Selection.ObjectType.PointOnElement, lastTip); //var first = firstrefer.GlobalPoint; //var last = firstrefer.GlobalPoint; //var elementByCurve = uidoc.Document.GetElement(firstrefer); //var firstPoint = elementByCurve.GetLocCurve().Project(first).XYZPoint; //var lastPoint = elementByCurve.GetLocCurve().Project(last).XYZPoint; #endregion var lc = element.Location as LocationCurve; var line = lc.Curve as Line; var doc = uidoc.Document; //获取剖面图类型 var viewfamilyType = doc.OfClass() .Cast() .Where(t => t.ViewFamily == ViewFamily.Section) .FirstOrDefault(); var bb = element.get_BoundingBox(null); var minZ = bb.Min.Z; var maxZ = bb.Max.Z; var baseLength = (bb.Max - bb.Min).GetLength(); ViewSection viewSection = null; BoundingBoxXYZ sectionBox; //transform.x:RightDirection,transform.y:UpDirection=Z轴,transform.z:ViewDirection (r x u=v) var t = Transform.Identity; Debug.WriteLine($"Length:{baseLength}"); Debug.WriteLine("拾取对象:"); Debug.WriteLine($"Min:{bb.Min}"); Debug.WriteLine($"Max:{bb.Max}"); //获得定位点 t.Origin = line.Evaluate(0.5, true).Flatten(); //t.Origin = line.GetEndPoint(0).Flatten(); Debug.WriteLine("定义剖面:"); Debug.WriteLine($"Transform.Origin:{t.Origin}"); t.BasisY = XYZ.BasisZ;//固定朝上UpDirection var viewName = $"{element.Category.Name}({element.Id})"; if (IsParallel) { //剖面视图中,裁剪框左下角的点 var min = new XYZ(-(baseLength + 1) / 2, minZ - 10, -2); //剖面视图中,裁剪框右上角的点 var max = new XYZ((baseLength + 1) / 2, maxZ + 10, 2); Debug.WriteLine($"Min:{min}"); Debug.WriteLine($"Max:{max}"); viewName = $"平行剖面-{viewName}"; t.BasisX = line.Direction;//与生成的最终剖面视图的RightDirection反向(定义Transform) t.BasisZ = line.Direction.CrossProduct(XYZ.BasisZ);//与生成的最终剖面视图的ViewDirection反向(定义Transform) Debug.WriteLine($"Transform.BasisX:{t.BasisX}"); Debug.WriteLine($"Transform.BasisZ:{t.BasisZ}"); sectionBox = new BoundingBoxXYZ { Transform = t, Min = min, Max = max }; } else { //var transform = line.ComputeDerivatives(0.5, true);//求导切向为BasisX viewName = $"正交剖面-{viewName}"; t.BasisX = XYZ.BasisZ.CrossProduct(line.Direction); t.BasisZ = line.Direction; var min = new XYZ(-5, minZ - 5, -2); var max = new XYZ(5, maxZ + 5, 2); Debug.WriteLine($"Transform.BasisX:{t.BasisX}"); Debug.WriteLine($"Transform.BasisZ:{t.BasisZ}"); try { sectionBox = new BoundingBoxXYZ { Transform = t, Min = min, Max = max }; } catch (Exception) { throw; } } doc.Invoke( ts => { if (sectionBox == null) { return; } viewSection = ViewSection.CreateSection(uidoc.Document, viewfamilyType.Id, sectionBox); viewSection.DisplayStyle = DisplayStyle.ShadingWithEdges; viewSection.DetailLevel = ViewDetailLevel.Fine; var isExistName = false; try { viewSection.Name = viewName; } catch (Autodesk.Revit.Exceptions.ArgumentException) { isExistName = true; } if (isExistName) { for (var i = 0; i < 100; i++) { try { viewSection.Name = $"{viewName} {i + 1}"; break; } catch (Autodesk.Revit.Exceptions.ArgumentException) { } } } ts.Commit(); if (viewSection != null) { viewSections.Add(viewSection); } Debug.WriteLine("生成后:"); Debug.WriteLine($"CropBox.Origin:{viewSection.CropBox.Transform.Origin}"); Debug.WriteLine($"CropBox.BasisX:{viewSection.CropBox.Transform.BasisX}"); Debug.WriteLine($"CropBox.BasisZ:{viewSection.CropBox.Transform.BasisZ}"); Debug.WriteLine($"CropBox.Min:{viewSection.CropBox.Min}"); Debug.WriteLine($"CropBox.Max:{viewSection.CropBox.Max}"); Debug.WriteLine($"RightDirection:{viewSection.RightDirection}"); Debug.WriteLine($"ViewDirection:{viewSection.ViewDirection}"); if (viewSection != null) { uidoc.ActiveView = viewSection; uidoc.Selection.SetElementIds([element.Id]); } }, "创建快速剖面"); }); } } }