using System.Collections.ObjectModel; using System.Diagnostics; 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)); 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; var offset = 0.2 * baseLength; var t = Transform.Identity; Debug.WriteLine($"Length:{baseLength}"); Debug.WriteLine($"Offset:{offset}"); Debug.WriteLine("拾取对象:"); Debug.WriteLine($"Min:{bb.Min}"); Debug.WriteLine($"Max:{bb.Max}"); t.Origin = line.Evaluate(0.5, true).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 / 2, minZ - offset, -offset); var max = new XYZ(baseLength / 2, maxZ + offset, offset); 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(-3000 / 304.8 / 2, minZ - offset, -offset); var max = new XYZ(3000 / 304.8 / 2, maxZ + offset, offset); Debug.WriteLine($"Transform.BasisX:{t.BasisX}"); Debug.WriteLine($"Transform.BasisZ:{t.BasisZ}"); sectionBox = new BoundingBoxXYZ { Transform = t, Min = min, Max = max }; } doc.Invoke( ts => { 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]); } }, "创建快速剖面"); }); } } }