Files
Shrlalgo.RvKits/Sai.RvKits/RvView/QuickViewSectionViewModel.cs

220 lines
9.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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<ViewSection> 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<ViewFamilyType>()
.Cast<ViewFamilyType>()
.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.xRightDirectiontransform.yUpDirection=Z轴transform.zViewDirection (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]);
}
}, "创建快速剖面");
});
}
}
}