2025-04-24 20:56:44 +08:00
|
|
|
|
using System.Diagnostics;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
using Autodesk.Revit.DB;
|
2024-12-22 10:26:12 +08:00
|
|
|
|
using Autodesk.Revit.UI.Selection;
|
2024-09-22 11:05:41 +08:00
|
|
|
|
using CommunityToolkit.Mvvm.ComponentModel;
|
|
|
|
|
|
using CommunityToolkit.Mvvm.Input;
|
|
|
|
|
|
using Nice3point.Revit.Toolkit.External.Handlers;
|
|
|
|
|
|
|
2025-02-10 20:53:40 +08:00
|
|
|
|
|
|
|
|
|
|
|
2025-04-24 20:56:44 +08:00
|
|
|
|
namespace ShrlAlgoToolkit.RevitAddins.RvView
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
2024-10-08 16:21:39 +08:00
|
|
|
|
public partial class QuickViewSectionViewModel : ObservableObject
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
private readonly ActionEventHandler handler = new();
|
|
|
|
|
|
|
|
|
|
|
|
[ObservableProperty]
|
2025-10-04 08:52:23 +08:00
|
|
|
|
public partial bool IsParallel { get; set; } = true;
|
|
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
private readonly List<ViewSection> viewSections = [];
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
|
|
|
|
|
[RelayCommand]
|
2024-10-08 16:21:39 +08:00
|
|
|
|
private void DeleteViewSection()
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
2024-10-08 16:21:39 +08:00
|
|
|
|
handler.Raise(
|
|
|
|
|
|
uiapp =>
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
2024-10-08 16:21:39 +08:00
|
|
|
|
var uidoc = uiapp.ActiveUIDocument;
|
|
|
|
|
|
var doc = uidoc.Document;
|
|
|
|
|
|
doc.Invoke(
|
2025-10-04 08:52:23 +08:00
|
|
|
|
_ =>
|
2024-10-08 16:21:39 +08:00
|
|
|
|
{
|
|
|
|
|
|
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;
|
2024-12-22 10:26:12 +08:00
|
|
|
|
var doc = uidoc.Document;
|
|
|
|
|
|
//var element = uidoc.SelectObject(new FuncFilter(elem => elem.GetCurve() is Line));
|
|
|
|
|
|
var placeProjectPoint = XYZ.Zero;
|
|
|
|
|
|
Line locLine = null;
|
|
|
|
|
|
XYZ lookDirection = null;
|
|
|
|
|
|
var depth = 4.0;
|
|
|
|
|
|
double baseLength = 4.0;
|
|
|
|
|
|
Element element;
|
|
|
|
|
|
if (IsParallel)
|
|
|
|
|
|
{
|
|
|
|
|
|
var refer = uidoc.Selection
|
|
|
|
|
|
.PickObject(
|
|
|
|
|
|
ObjectType.PointOnElement,
|
|
|
|
|
|
new FuncFilter(elem => elem.GetCurve() is Line),
|
|
|
|
|
|
"请选择前进方向起点(剖面看向将会在前进方向左侧)");
|
|
|
|
|
|
var refer1 = uidoc.Selection
|
|
|
|
|
|
.PickObject(
|
|
|
|
|
|
ObjectType.PointOnElement,
|
|
|
|
|
|
new FuncFilter(elem => elem.Id == refer.ElementId),
|
|
|
|
|
|
"请选择前进方向终点(剖面看向将会在前进方向左侧)");
|
|
|
|
|
|
element = doc.GetElement(refer);
|
|
|
|
|
|
|
|
|
|
|
|
var startPointPicked = refer.GlobalPoint;
|
|
|
|
|
|
var startProjectPoint = element.GetCurve().Project(startPointPicked).XYZPoint;
|
|
|
|
|
|
//终点投影
|
|
|
|
|
|
var forwardPointPicked = refer1.GlobalPoint;
|
|
|
|
|
|
var forwardProjectPoint = element.GetCurve().Project(forwardPointPicked).XYZPoint;
|
|
|
|
|
|
//前进方向
|
|
|
|
|
|
var d = forwardProjectPoint - startProjectPoint;
|
|
|
|
|
|
//剖面宽度、跨度
|
|
|
|
|
|
baseLength = d.GetLength();
|
|
|
|
|
|
//左侧
|
|
|
|
|
|
lookDirection = XYZ.BasisZ.CrossProduct(forwardProjectPoint - startProjectPoint).Normalize();
|
|
|
|
|
|
|
|
|
|
|
|
//中点,向查看方向反向移动,用于平行剖面的放置
|
|
|
|
|
|
placeProjectPoint = (forwardProjectPoint + startProjectPoint) / 2 - lookDirection;
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
var refer = uidoc.Selection
|
|
|
|
|
|
.PickObject(
|
|
|
|
|
|
ObjectType.PointOnElement,
|
|
|
|
|
|
new FuncFilter(elem => elem.GetCurve() is Line),
|
|
|
|
|
|
"请选择放置剖面位置");
|
|
|
|
|
|
var refer1 = uidoc.Selection
|
|
|
|
|
|
.PickObject(
|
|
|
|
|
|
ObjectType.PointOnElement,
|
|
|
|
|
|
new FuncFilter(elem => elem.Id == refer.ElementId),
|
|
|
|
|
|
"剖面看向方向和相对剖面放置的深度");
|
|
|
|
|
|
element = doc.GetElement(refer);
|
|
|
|
|
|
//正交剖面的放置位置
|
|
|
|
|
|
var placePointPicked = refer.GlobalPoint;
|
|
|
|
|
|
placeProjectPoint = element.GetCurve().Project(placePointPicked).XYZPoint;
|
|
|
|
|
|
//深度的投影
|
|
|
|
|
|
var lookPointPicked = refer1.GlobalPoint;
|
|
|
|
|
|
var lookProjectPoint = element.GetCurve().Project(lookPointPicked).XYZPoint;
|
|
|
|
|
|
|
|
|
|
|
|
depth = placeProjectPoint.DistanceTo(lookProjectPoint);
|
|
|
|
|
|
|
|
|
|
|
|
//if (locLine.Direction.IsAlmostEqualTo((lookPointPicked - startPointPicked).Normalize()))
|
|
|
|
|
|
//{
|
|
|
|
|
|
//}
|
|
|
|
|
|
lookDirection = (lookProjectPoint - placeProjectPoint).Normalize();
|
|
|
|
|
|
}
|
|
|
|
|
|
locLine = element.GetCurve() as Line;
|
2024-10-27 00:19:48 +08:00
|
|
|
|
#region 选择方向
|
|
|
|
|
|
//var firstTip = "请选择第一个点以确定正交剖面的定位点";
|
|
|
|
|
|
//var lastTip = "请选择第二个点以确定拉抻的深度";
|
|
|
|
|
|
//if (IsParallel)
|
|
|
|
|
|
//{
|
|
|
|
|
|
// firstTip = "请选择第一个剖面范围水平的边界点";
|
|
|
|
|
|
// lastTip = "请选择第二个剖面范围水平的边界点";
|
|
|
|
|
|
//}
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//var firstrefer = uiapp.Selection
|
2024-10-27 00:19:48 +08:00
|
|
|
|
// .PickObject(Autodesk.Revit.UI.Selection.ObjectType.PointOnElement, firstTip);
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//var lastrefer = uiapp.Selection
|
2024-10-27 00:19:48 +08:00
|
|
|
|
// .PickObject(Autodesk.Revit.UI.Selection.ObjectType.PointOnElement, lastTip);
|
|
|
|
|
|
//var first = firstrefer.GlobalPoint;
|
|
|
|
|
|
//var last = firstrefer.GlobalPoint;
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//var elementByCurve = uiapp.Document.GetElement(firstrefer);
|
2024-10-27 00:19:48 +08:00
|
|
|
|
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//var firstProjectPoint = elementByCurve.GetCurve().Project(first).XYZPoint;
|
|
|
|
|
|
//var lookProjectPoint = elementByCurve.GetCurve().Project(last).XYZPoint;
|
2024-10-27 00:19:48 +08:00
|
|
|
|
#endregion
|
|
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
var bb = element.get_BoundingBox(null);
|
|
|
|
|
|
var minZ = bb.Min.Z;
|
|
|
|
|
|
var maxZ = bb.Max.Z;
|
|
|
|
|
|
|
|
|
|
|
|
ViewSection viewSection = null;
|
|
|
|
|
|
BoundingBoxXYZ sectionBox;
|
2024-10-27 00:19:48 +08:00
|
|
|
|
//transform.x:RightDirection,transform.y:UpDirection=Z轴,transform.z:ViewDirection (r x u=v)
|
2024-10-08 16:21:39 +08:00
|
|
|
|
var t = Transform.Identity;
|
|
|
|
|
|
Debug.WriteLine($"Length:{baseLength}");
|
|
|
|
|
|
Debug.WriteLine("拾取对象:");
|
|
|
|
|
|
|
|
|
|
|
|
Debug.WriteLine($"Min:{bb.Min}");
|
|
|
|
|
|
Debug.WriteLine($"Max:{bb.Max}");
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//设置定位点
|
|
|
|
|
|
//t.Origin = line.Evaluate(0.5, true).Flatten();
|
|
|
|
|
|
t.Origin = placeProjectPoint.Flatten();
|
2024-10-27 00:19:48 +08:00
|
|
|
|
//t.Origin = line.GetEndPoint(0).Flatten();
|
2024-10-08 16:21:39 +08:00
|
|
|
|
Debug.WriteLine("定义剖面:");
|
|
|
|
|
|
Debug.WriteLine($"Transform.Origin:{t.Origin}");
|
2024-10-27 00:19:48 +08:00
|
|
|
|
t.BasisY = XYZ.BasisZ;//固定朝上UpDirection
|
2024-10-08 16:21:39 +08:00
|
|
|
|
var viewName = $"{element.Category.Name}({element.Id})";
|
|
|
|
|
|
if (IsParallel)
|
|
|
|
|
|
{
|
2024-10-27 00:19:48 +08:00
|
|
|
|
//剖面视图中,裁剪框左下角的点
|
2024-12-22 10:26:12 +08:00
|
|
|
|
var min = new XYZ(-(baseLength) / 2, minZ - 10, 0);
|
2024-10-27 00:19:48 +08:00
|
|
|
|
//剖面视图中,裁剪框右上角的点
|
2024-12-22 10:26:12 +08:00
|
|
|
|
var max = new XYZ((baseLength) / 2, maxZ + 10, depth);
|
2024-10-08 16:21:39 +08:00
|
|
|
|
Debug.WriteLine($"Min:{min}");
|
|
|
|
|
|
Debug.WriteLine($"Max:{max}");
|
|
|
|
|
|
|
|
|
|
|
|
viewName = $"平行剖面-{viewName}";
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//与生成的最终剖面视图的RightDirection反向(定义Transform)
|
|
|
|
|
|
t.BasisX = XYZ.BasisZ.CrossProduct(lookDirection).Normalize();
|
|
|
|
|
|
//与生成的最终剖面视图的ViewDirection反向(定义Transform)
|
|
|
|
|
|
t.BasisZ = lookDirection;
|
2024-10-27 00:19:48 +08:00
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
Debug.WriteLine($"Transform.BasisX:{t.BasisX}");
|
|
|
|
|
|
Debug.WriteLine($"Transform.BasisZ:{t.BasisZ}");
|
|
|
|
|
|
|
|
|
|
|
|
sectionBox = new BoundingBoxXYZ
|
|
|
|
|
|
{
|
|
|
|
|
|
Transform = t,
|
|
|
|
|
|
Min = min,
|
|
|
|
|
|
Max = max
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
2024-10-08 16:21:39 +08:00
|
|
|
|
//var transform = line.ComputeDerivatives(0.5, true);//求导切向为BasisX
|
|
|
|
|
|
viewName = $"正交剖面-{viewName}";
|
2024-12-22 10:26:12 +08:00
|
|
|
|
t.BasisX = XYZ.BasisZ.CrossProduct(locLine.Direction).Normalize();
|
|
|
|
|
|
t.BasisZ = locLine.Direction;
|
|
|
|
|
|
var min = new XYZ(-10, minZ - 5, 0);
|
|
|
|
|
|
var max = new XYZ(10, maxZ + 5, depth);
|
2024-10-08 16:21:39 +08:00
|
|
|
|
|
|
|
|
|
|
Debug.WriteLine($"Transform.BasisX:{t.BasisX}");
|
|
|
|
|
|
Debug.WriteLine($"Transform.BasisZ:{t.BasisZ}");
|
2024-10-27 00:19:48 +08:00
|
|
|
|
try
|
2024-10-08 16:21:39 +08:00
|
|
|
|
{
|
2024-10-27 00:19:48 +08:00
|
|
|
|
sectionBox = new BoundingBoxXYZ
|
|
|
|
|
|
{
|
|
|
|
|
|
Transform = t,
|
|
|
|
|
|
Min = min,
|
|
|
|
|
|
Max = max
|
|
|
|
|
|
};
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Exception)
|
|
|
|
|
|
{
|
|
|
|
|
|
throw;
|
|
|
|
|
|
}
|
2024-10-08 16:21:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
doc.Invoke(
|
|
|
|
|
|
ts =>
|
|
|
|
|
|
{
|
2024-10-27 00:19:48 +08:00
|
|
|
|
if (sectionBox == null)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
2024-12-22 10:26:12 +08:00
|
|
|
|
//获取剖面图类型
|
|
|
|
|
|
var viewfamilyType = doc.OfClass<ViewFamilyType>()
|
|
|
|
|
|
.Cast<ViewFamilyType>()
|
|
|
|
|
|
.Where(t => t.ViewFamily == ViewFamily.Section)
|
|
|
|
|
|
.FirstOrDefault();
|
2024-10-08 16:21:39 +08:00
|
|
|
|
viewSection = ViewSection.CreateSection(uidoc.Document, viewfamilyType.Id, sectionBox);
|
|
|
|
|
|
viewSection.DisplayStyle = DisplayStyle.ShadingWithEdges;
|
|
|
|
|
|
viewSection.DetailLevel = ViewDetailLevel.Fine;
|
|
|
|
|
|
var isExistName = false;
|
|
|
|
|
|
try
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
2024-10-08 16:21:39 +08:00
|
|
|
|
viewSection.Name = viewName;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Autodesk.Revit.Exceptions.ArgumentException)
|
|
|
|
|
|
{
|
|
|
|
|
|
isExistName = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
if (isExistName)
|
|
|
|
|
|
{
|
|
|
|
|
|
for (var i = 0; i < 100; i++)
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
2024-10-08 16:21:39 +08:00
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
viewSection.Name = $"{viewName} {i + 1}";
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
|
|
|
|
|
catch (Autodesk.Revit.Exceptions.ArgumentException)
|
2024-09-22 11:05:41 +08:00
|
|
|
|
{
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
2024-10-08 16:21:39 +08:00
|
|
|
|
}
|
|
|
|
|
|
ts.Commit();
|
|
|
|
|
|
if (viewSection != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
viewSections.Add(viewSection);
|
|
|
|
|
|
}
|
|
|
|
|
|
Debug.WriteLine("生成后:");
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
Debug.WriteLine($"CropBox.Origin:{viewSection.CropBox.Transform.Origin}");
|
|
|
|
|
|
Debug.WriteLine($"CropBox.BasisX:{viewSection.CropBox.Transform.BasisX}");
|
|
|
|
|
|
Debug.WriteLine($"CropBox.BasisZ:{viewSection.CropBox.Transform.BasisZ}");
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
Debug.WriteLine($"CropBox.Min:{viewSection.CropBox.Min}");
|
|
|
|
|
|
Debug.WriteLine($"CropBox.Max:{viewSection.CropBox.Max}");
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
Debug.WriteLine($"RightDirection:{viewSection.RightDirection}");
|
|
|
|
|
|
Debug.WriteLine($"ViewDirection:{viewSection.ViewDirection}");
|
2024-09-22 11:05:41 +08:00
|
|
|
|
|
2024-10-08 16:21:39 +08:00
|
|
|
|
if (viewSection != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
uidoc.ActiveView = viewSection;
|
|
|
|
|
|
uidoc.Selection.SetElementIds([element.Id]);
|
|
|
|
|
|
}
|
|
|
|
|
|
}, "创建快速剖面");
|
|
|
|
|
|
});
|
2024-09-22 11:05:41 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|