Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/Deco/BricksFinishesViewModel.cs
2026-02-22 20:03:42 +08:00

841 lines
32 KiB
C#
Raw Permalink 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.ComponentModel.DataAnnotations;
using System.Windows;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Architecture;
using Autodesk.Revit.UI.Selection;
using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using Nice3point.Revit.Toolkit.External.Handlers;
namespace ShrlAlgoToolkit.RevitAddins.RvCivil;
public partial class BricksFinishesViewModel : ObservableValidator
{
public BricksFinishesViewModel()
{
//ErrorsChanged += BricksFinishesViewModel_ErrorsChanged;
finishesHandler = new ActionEventHandler();
PavementLength = 600;
PavementWidth = 600;
PavementGap = 2;
WallBaseOffset = 0;
PavementThickness = 2;
PanelName = "铺砖";
}
//~BricksFinishesViewModel()
//{
// ErrorsChanged -= BricksFinishesViewModel_ErrorsChanged;
//}
//private void BricksFinishesViewModel_ErrorsChanged(object sender, System.ComponentModel.DataErrorsChangedEventArgs e)
//{
// MessageBox.Show(GetErrors().FirstOrDefault().ErrorMessage, "错误", MessageBoxButton.OK, MessageBoxImage.Error);
//}
private readonly ActionEventHandler finishesHandler;
[ObservableProperty]
public partial bool ByRoom { get; set; }
//边界限具有缝隙
[ObservableProperty]
public partial bool IsEdgeExistGap { get; set; }
[Required(ErrorMessage = "不可为空")]
[Common.Attributes.IsNumeric]
[Common.Attributes.Minimum(10.0)]
[ObservableProperty]
[NotifyDataErrorInfo]
public partial double PavementWidth { get; set; }
//public double PavementWidth
//{
// get => pavementWidth;
// set => SetProperty(ref pavementWidth, value, true);
//}
[Required(ErrorMessage = "不可为空")]
[Common.Attributes.IsNumeric]
[ObservableProperty]
[NotifyDataErrorInfo]
public partial double WallBaseOffset { get; set; }
// public double WallBaseOffset
//{
// get => wallBaseOffset;
// set => SetProperty(ref wallBaseOffset, value, true);
//}
[Required(ErrorMessage = "不可为空")]
[Common.Attributes.IsNumeric]
[Common.Attributes.Minimum(1.0)]
[ObservableProperty]
[NotifyDataErrorInfo]
public partial double PavementThickness { get; set; }
// public double PavementThickness
//{
// get => pavementThickness;
// set => SetProperty(ref pavementThickness, value, true);
//}
[Required(ErrorMessage = "不可为空")]
[Common.Attributes.IsNumeric]
[Common.Attributes.Minimum(10.0)]
[ObservableProperty]
[NotifyDataErrorInfo]
public partial double PavementLength { get; set; }
// public double PavementLength
//{
// get => pavementLength;
// set => SetProperty(ref pavementLength, value, true);
//}
[Required(ErrorMessage = "不可为空")]
[Common.Attributes.IsNumeric]
[Common.Attributes.Minimum(1.0)]
[ObservableProperty]
[NotifyDataErrorInfo]
public partial double PavementGap { get; set; }
// public double PavementGap
//{
// get => pavementGap;
// set => SetProperty(ref pavementGap, value, true);
//}
[Required(ErrorMessage = "不可为空")]
[MinLength(1)]
[ObservableProperty]
[NotifyDataErrorInfo]
public partial string PanelName { get; set; }
// public string PanelName
//{
// get => panelName;
// set
// {
// SetProperty(ref panelName, value, true);
// PlaceBricksCommand.NotifyCanExecuteChanged();
// }
//}
private static CurtainSystemType SetCurtainSystemType(Document doc, double length, double width, double gap, double thickness, string panelName)
{
var curtainSystemTypeCollector = new FilteredElementCollector(doc)
.OfClass(typeof(CurtainSystemType))
.OfCategory(BuiltInCategory.OST_CurtaSystem)
.Cast<CurtainSystemType>()
.ToList();
var panelTypeCollector = new FilteredElementCollector(doc)
.OfClass(typeof(PanelType))
.OfCategory(BuiltInCategory.OST_CurtainWallPanels)
.Cast<PanelType>()
.ToList();
var curtainWallMullionsTypeCollector = new FilteredElementCollector(doc)
.OfClass(typeof(MullionType))
.OfCategory(BuiltInCategory.OST_CurtainWallMullions)
.Cast<MullionType>()
.ToList();
CurtainSystemType curtainSystemType = null;
PanelType panelType = null;
MullionType mullionType = null;
var curtainSystemTypeName = $"铺砖-{length}mm x {width}mm";
var panelTypeName = panelName;
var mullionTypeName = $"{gap}mm x {thickness}mm";
//创建嵌板类型
try
{
var defaultPanelType = panelTypeCollector.FirstOrDefault();
panelType = defaultPanelType.Duplicate(panelTypeName) as PanelType;
}
catch (Autodesk.Revit.Exceptions.ArgumentException)
{
foreach (var t in panelTypeCollector)
{
if (t.Name == panelTypeName)
{
panelType = t;
break;
}
}
}
panelType?.get_Parameter(BuiltInParameter.CURTAIN_WALL_SYSPANEL_THICKNESS).Set(thickness / 304.8);
//嵌板偏移
panelType?.get_Parameter(BuiltInParameter.CURTAIN_WALL_SYSPANEL_OFFSET).Set(0);
//创建竖挺类型
try
{
var defaultMullionType = curtainWallMullionsTypeCollector.FirstOrDefault(
m => m.FamilyName.Contains("矩形") || m.FamilyName.Contains("Rectangular")
);
mullionType = defaultMullionType.Duplicate(mullionTypeName) as MullionType;
}
catch (Autodesk.Revit.Exceptions.ArgumentException)
{
foreach (var t in curtainWallMullionsTypeCollector)
{
if (t.Name == mullionTypeName)
{
mullionType = t;
break;
}
}
}
//设置参数
mullionType?.get_Parameter(BuiltInParameter.RECT_MULLION_WIDTH1).Set(gap / 304.8 / 2);
mullionType?.get_Parameter(BuiltInParameter.RECT_MULLION_WIDTH2).Set(gap / 304.8 / 2);
mullionType?.get_Parameter(BuiltInParameter.RECT_MULLION_THICK).Set(thickness / 304.8);
//创建幕墙系统类型
try
{
var defaultCurtainSystemType = curtainSystemTypeCollector.FirstOrDefault();
curtainSystemType = defaultCurtainSystemType.Duplicate(curtainSystemTypeName) as CurtainSystemType;
}
catch (Autodesk.Revit.Exceptions.ArgumentException)
{
foreach (var t in curtainSystemTypeCollector)
{
if (t.Name == curtainSystemTypeName)
{
curtainSystemType = t;
break;
}
}
}
//mullionType.get_Parameter(BuiltInParameter.MULLION_OFFSET).Set(0);
//mullionType.get_Parameter(BuiltInParameter.MULLION_OFFSET).Set(thickness / 304.8 );
curtainSystemType?.get_Parameter(BuiltInParameter.SPACING_LAYOUT_1).Set(1);
curtainSystemType?.get_Parameter(BuiltInParameter.SPACING_LAYOUT_2).Set(1);
//panelType.get_Parameter(BuiltInParameter.CURTAIN_WALL_SYSPANEL_OFFSET).Set(-thickness / 304.8 / 2);
curtainSystemType?.get_Parameter(BuiltInParameter.SPACING_LENGTH_1).Set((width + gap) / 304.8);
curtainSystemType?.get_Parameter(BuiltInParameter.SPACING_LENGTH_2).Set((length + gap) / 304.8);
if (mullionType != null && panelType != null)
{
curtainSystemType?.get_Parameter(BuiltInParameter.AUTO_PANEL).Set(panelType.Id);
curtainSystemType?.get_Parameter(BuiltInParameter.AUTO_MULLION_INTERIOR_GRID1).Set(mullionType.Id);
curtainSystemType?.get_Parameter(BuiltInParameter.AUTO_MULLION_INTERIOR_GRID2).Set(mullionType.Id);
}
curtainSystemType?.get_Parameter(BuiltInParameter.CURTAINGRID_ADJUST_BORDER_1).Set(1);
curtainSystemType?.get_Parameter(BuiltInParameter.CURTAINGRID_ADJUST_BORDER_2).Set(1);
//curtainSystemType.get_Parameter(BuiltInParameter.AUTO_MULLION_BORDER1_GRID1).Set(mullionType.ViewId);
//curtainSystemType.get_Parameter(BuiltInParameter.AUTO_MULLION_BORDER1_GRID2).Set(mullionType.ViewId);
//curtainSystemType.get_Parameter(BuiltInParameter.AUTO_MULLION_BORDER2_GRID1).Set(mullionType.ViewId);
//curtainSystemType.get_Parameter(BuiltInParameter.AUTO_MULLION_BORDER2_GRID2).Set(mullionType.ViewId);
return curtainSystemType;
}
/// <summary>
/// 获取偏移量
/// </summary>
/// <param name="coord">UV平面坐标系</param>
/// <param name="start">拾取的起铺点</param>
/// <returns></returns>
private static double[,] GetOffset(List<XYZ> coord, XYZ start)
{
var origin = coord[0];
//var insterIntersectionResult = line.ProjectOf(origin);
//var project = insterIntersectionResult?.XYZPoint;
//var dis = insterIntersectionResult?.DistanceX;
//var uDirection = XYZ.Zero;
//var vDirection = XYZ.Zero;
//bool lineIsU = false;
double uoffest;
double voffest;
var p = start - origin;
//u轴进行的偏移实际是v轴沿着u轴的偏移值故应相反设置偏移值
//因为轴的模长度为1所以直接等于p在轴上的投影长度
uoffest = p.DotProduct(coord[1]);
//if (coord[1].CrossProduct(p).Z < 0)
//{
// uoffest = -uoffest;
//}
voffest = p.DotProduct(coord[2]);
//if (coord[2].CrossProduct(p).Z < 0)
//{
// voffest = -voffest;
//}
//if (coord[1].CrossProduct(line.Direction).IsAlmostEqualTo(XYZ.Zero))
//{
// uoffest = coord[1].DotProduct(p) * coord[1];
// voffest = coord[2].DotProduct(p) * coord[2];
// ////得到起铺点相对幕墙系统原点的偏移量
// //double offest = default;
// //if ((start - origin).Normalize().IsAlmostEqualTo(coord[1]))
// //{
// // offest = (start - origin).GetLength();
// //}
// //else
// //{
// // offest = -(start - origin).GetLength();
// //}
// //result.Add(coord[1], offest);//u
// //if ((project - origin).Normalize().IsAlmostEqualTo(coord[2]))
// //{
// // offest = (project - origin).GetLength();
// //}
// //else
// //{
// // offest = -(project - origin).GetLength();
// //}
// //result.Add(coord[2], offest);//v
//}
//else if (coord[2].CrossProduct(line.Direction).IsAlmostEqualTo(XYZ.Zero))
//{
// isInvert = true;
// uoffest = coord[2].DotProduct(p) * coord[2];
// voffest = coord[1].DotProduct(p) * coord[1];
// //double offest = default;
// //if ((project - origin).Normalize().IsAlmostEqualTo(coord[1]))
// //{
// // offest = (project - origin).GetLength();
// //}
// //else
// //{
// // offest = -(project - origin).GetLength();
// //}
// //result.Add(coord[1], offest);//v
// //if ((start - origin).DotProduct(coord[1]) > 0)
// //{
// // offest = (start - origin).GetLength();
// //}
// //else
// //{
// // offest = -(start - origin).GetLength();
// //}
// //result.Add(coord[1], offest);//v
//}
////if (project != null)
////{
//// var offset = project.DistanceTo(start);
//// //判断正方向还是反方向
//// if ((start - project).Normalize().IsAlmostEqualTo(-coord[1]))
//// {
//// offset = -offset;
//// }
//// //var direction = XYZ.BasisZ.CrossProduct(pl.FaceNormal);
//// //if (direction.IsAlmostEqualTo(line.Direction))
//// //{
//// // offset = xyz.DistanceTo(startPoint) * 304.8;
//// //}
//// //else
//// //{
//// // offset = xyz.DistanceTo(endPoint) * 304.8;
//// //}
//// //offset = x;
//// var n = Math.Floor(offset / interval);
//// offset -= Math.Floor(n) * interval;
//// return offset;
////}
//if (voffest == null || uoffest == null)
//{
// return null;
//}
return new[,]
{
{ uoffest, voffest }
};
}
private static FaceArray GetFaceArray(Document doc, List<CurveLoop> curveLoops, out DirectShape ds)
{
FaceArray array = new();
var solid = GeometryCreationUtilities.CreateExtrusionGeometry(curveLoops, -XYZ.BasisZ, 10.0);
ds = DirectShape.CreateElement(doc, new ElementId(BuiltInCategory.OST_Mass));
ds?.AppendShape(new List<GeometryObject> { solid });
foreach (Face face in solid.Faces)
{
var pf = face as PlanarFace;
if (pf.FaceNormal.IsAlmostEqualTo(XYZ.BasisZ))
{
array.Append(face);
break;
}
}
return array;
}
/// <summary>
/// 获取最终幕墙系统坐标
/// </summary>
/// <param name="doc"></param>
/// <param name="array"></param>
/// <param name="line"></param>
/// <param name="rotation"></param>
/// <returns></returns>
private static List<XYZ> GetCoordinateSystem(Document doc, FaceArray array, Line line, out Rotation rotation)
{
var curtainSystemTypeCollector = new FilteredElementCollector(doc)
.OfClass(typeof(CurtainSystemType))
.OfCategory(BuiltInCategory.OST_CurtaSystem);
XYZ origin = null;
XYZ u = null;
XYZ v = null;
rotation = null;
using (Transaction trans = new(doc, "获取坐标系"))
{
trans.Start();
if (curtainSystemTypeCollector.FirstOrDefault() is CurtainSystemType defaultCurtainSystemType)
{
defaultCurtainSystemType.get_Parameter(BuiltInParameter.SPACING_LAYOUT_1).Set(2);
defaultCurtainSystemType.get_Parameter(BuiltInParameter.SPACING_LAYOUT_2).Set(2);
var curtainSystem = doc.Create.NewCurtainSystem(array, defaultCurtainSystemType);
//编号
curtainSystem.get_Parameter(BuiltInParameter.SPACING_NUM_DIVISIONS_1).Set(1);
curtainSystem.get_Parameter(BuiltInParameter.SPACING_NUM_DIVISIONS_2).Set(1);
//对正
curtainSystem.get_Parameter(BuiltInParameter.SPACING_JUSTIFICATION_1).Set(2);
curtainSystem.get_Parameter(BuiltInParameter.SPACING_JUSTIFICATION_2).Set(2);
//
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ORIGIN_1).Set(0);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ORIGIN_2).Set(0);
doc.Regenerate();
origin = GetOrigin(doc, curtainSystem, out u, out v);
var list = new List<XYZ> { origin, u, v };
//获取旋转角度
rotation = GetRotation(list, line);
//设置旋转角
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ANGLE_1).Set(rotation.Radian);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ANGLE_2).Set(rotation.Radian);
//得到转换后的角度
doc.Regenerate();
origin = GetOrigin(doc, curtainSystem, out u, out v);
}
trans.RollBack();
//trans.Commit();
}
return [origin, u, v];
}
/// <summary>
/// 得到旋转角度
/// </summary>
/// <param name="coordSystem"></param>
/// <param name="line"></param>
/// <returns></returns>
private static Rotation GetRotation(List<XYZ> coordSystem, Line line)
{
var radian1 = coordSystem[1].AngleTo(line.Direction);
Rotation rotation1 =
new()
{
Radian = radian1,
Direction = line.Direction,
Orientation = Orientation.U,
CoordSystemAxis = coordSystem[1]
};
var radian2 = coordSystem[1].AngleTo(-line.Direction);
Rotation rotation2 =
new()
{
Radian = radian2,
Direction = -line.Direction,
Orientation = Orientation.U,
CoordSystemAxis = coordSystem[1]
};
var radian3 = coordSystem[2].AngleTo(line.Direction);
Rotation rotation3 =
new()
{
Radian = radian3,
Direction = line.Direction,
Orientation = Orientation.V,
CoordSystemAxis = coordSystem[2]
};
var radian4 = coordSystem[2].AngleTo(-line.Direction);
Rotation rotation4 =
new()
{
Radian = radian4,
Direction = -line.Direction,
Orientation = Orientation.V,
CoordSystemAxis = coordSystem[2]
};
List<Rotation> rotations = [rotation1, rotation2, rotation3, rotation4];
var rotation = rotations.OrderBy(r => r.Radian).First();
if (rotation.CoordSystemAxis.CrossProduct(rotation.Direction).Z < 0)
{
rotation.Radian = -rotation.Radian;
}
return rotation;
//double radian;
////grid2的轴向单位向量
////在平面
//if (pl.FaceNormal.IsAlmostEqualTo(XYZ.BasisZ))
//{
// var perpendicularVector = line.Direction.CrossProduct(XYZ.BasisZ);
// if (perpendicularVector.Y < 0)
// {
// perpendicularVector = -perpendicularVector;
// }
// radian = perpendicularVector.X > 0 ? -perpendicularVector.AngleTo(XYZ.BasisY) : perpendicularVector.AngleTo(XYZ.BasisY);
// //angle = radian * 180 / Math.PI;
// if (Math.Abs(Math.Round(radian, MidpointRounding.AwayFromZero) - Math.PI / 2) < 0.0001)
// {
// radian = 0;
// }
//}
//else//在垂直面
//{
// radian = 0;
//}
//return radian;
}
private static void CreateCurtainSystemByFace(
UIDocument uidoc,
double length,
double width,
double gap,
double thickness,
double wallBaseOffset,
string panelName,
bool isEdgeExistGap
)
{
var doc = uidoc.Document;
var faceReference = uidoc.Selection.PickObject(ObjectType.Face, "请选择铺贴的面");
var element = doc.GetElement(faceReference);
double baseHeight = default;
double height = default;
doc.InvokeGroup(
_ =>
{
if (element is Wall)
{
doc.Invoke(
_ =>
{
//顶部约束
var topConstraint = element.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
if (topConstraint == ElementId.InvalidElementId) //未连接
{
//无连接高度
height = element.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();
element.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).Set(height - (wallBaseOffset / 304.8));
}
baseHeight = element.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).AsDouble();
element.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(baseHeight + (wallBaseOffset / 304.8));
},
"设置墙底部高度"
);
}
var face = element.GetGeometryObjectFromReference(faceReference) as Face;
var pl = face as PlanarFace;
if (pl == null)
{
return;
}
double radian = 0;
double actualU = 0;
double actualV = 0;
FaceArray array = new();
array.Append(face);
var referEdge = uidoc.Selection.PickObject(ObjectType.Edge, new EdgeFilter(element), "请选择对齐的边");
var xyz = uidoc.Selection.PickPoint(
ObjectSnapTypes.Intersections
| ObjectSnapTypes.Endpoints
| ObjectSnapTypes.Centers
| ObjectSnapTypes.Midpoints
| ObjectSnapTypes.Points
| ObjectSnapTypes.Nearest
| ObjectSnapTypes.Perpendicular
| ObjectSnapTypes.WorkPlaneGrid
| ObjectSnapTypes.Quadrants
| ObjectSnapTypes.Tangents,
"请选择起铺点"
);
var edgeObj = element.GetGeometryObjectFromReference(referEdge) as Edge;
//var ourterEdgeArray = face.EdgeLoops.get_Item(0);
if (edgeObj != null && edgeObj.AsCurve() is Line)
{
var line = edgeObj.AsCurve() as Line;
var coordinateSystem = GetCoordinateSystem(doc, array, line, out var rotation);
var startPoint = line!.GetEndPoint(0);
var endPoint = line.GetEndPoint(1);
var start = line.Project(xyz).XYZPoint;
var totalLength = start.DistanceTo(startPoint) + start.DistanceTo(endPoint);
//判断点是否在直线上
if (totalLength - line.Length > 0.0001)
{
MessageBox.Show("选择点不在对齐的边上", "错误");
return;
}
radian = rotation.Radian;
var uv = GetOffset(coordinateSystem, start);
if (uv != null)
{
//原始起铺点基于幕墙系统原点平面uv偏移量
var intervalU = (length + gap) / 304.8;
var intervalV = (width + gap) / 304.8;
var n = Math.Floor(uv[0, 0] / intervalU);
var m = Math.Floor(uv[0, 1] / intervalV);
if (isEdgeExistGap)
{
actualU = uv[0, 0] - (n * intervalU);
actualV = uv[0, 1] - (m * intervalV);
}
else
{
actualU = uv[0, 0] - (n * intervalU) - (gap / 2 / 304.8);
actualV = uv[0, 1] - (m * intervalV) - (gap / 2 / 304.8);
}
}
}
CurtainSystem curtainSystem = null;
//doc.Regenerate();
doc.Invoke(
_ =>
{
var curtainSystemType = SetCurtainSystemType(doc, length, width, gap, thickness, panelName);
curtainSystem = doc.Create.NewCurtainSystem(array, curtainSystemType);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ANGLE_1).Set(radian);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ANGLE_2).Set(radian);
doc.Regenerate();
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ORIGIN_1).Set(actualU);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ORIGIN_2).Set(actualV);
curtainSystem.get_Parameter(BuiltInParameter.SPACING_JUSTIFICATION_1).Set(2);
curtainSystem.get_Parameter(BuiltInParameter.SPACING_JUSTIFICATION_2).Set(2);
ElementTransformUtils.MoveElement(doc, curtainSystem.Id, pl.FaceNormal * thickness / 304.8 / 2);
},
"创建幕墙系统"
);
if (element is Wall)
{
doc.Invoke(
_ =>
{
element.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).Set(baseHeight);
var topConstraint = element.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
if (topConstraint == ElementId.InvalidElementId) //未连接
{
//无连接高度
element.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).Set(height);
}
},
"设置墙偏移"
);
}
if (curtainSystem != null)
{
doc.Invoke(_ =>
{
var iterator = curtainSystem.CurtainGrids.ForwardIterator();
iterator.MoveNext();
var grid = iterator.Current as CurtainGrid;
var panels = grid!.GetPanelIds().Select(id => doc.GetElement(id) as Panel);
var area = width / 304.8 * length / 304.8;
var errorPanels =
from panel in panels
where panel!.get_Parameter(BuiltInParameter.HOST_AREA_COMPUTED).AsDouble() < area / 4
select panel;
foreach (var panel in errorPanels)
{
var overrideGraphicSettings = doc.ActiveView.GetElementOverrides(panel.Id);
overrideGraphicSettings.SetProjectionLineColor(new Color(255, 0, 0));
//在当前视图下设置,其它视图保持原来的
doc.ActiveView.SetElementOverrides(panel.Id, overrideGraphicSettings);
doc.Regenerate();
}
});
}
},
"创建饰面"
);
//CreateCurtainSystem(length, width, gap, thickness, angle, offset, doc, curveLoops, pl.FaceNormal);
//var xyz = referEdge.GlobalPoint;
//if (angle > Math.PI / 2)
//{
// angle -= Math.PI;
// if (perpendicularVector.Y>0)
// {
// angle -= Math.PI / 2 ;
// }
// else
// {
// angle = Math.PI / 2 - angle;
// }
//}
}
private static void CreateCurtainSystemByRoom(UIDocument uidoc, double length, double width, double gap, double thickness, string panelName)
{
var doc = uidoc.Document;
var rooms = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_Rooms);
if (!rooms.Any())
{
MessageBox.Show("项目中当前没有房间", "提示", MessageBoxButton.OK, MessageBoxImage.Stop);
return;
}
var refer = uidoc.Selection.PickObject(ObjectType.Element, new GenericFilter<Room>(), "请选择铺贴的房间");
var room = doc.GetElement(refer) as Room;
List<CurveLoop> curveLoops = [];
var opts = new SpatialElementBoundaryOptions();
var segmentsList = room!.GetBoundarySegments(opts);
if (segmentsList != null)
{
foreach (var boundarySegments in segmentsList)
{
CurveLoop curveLoop = new();
foreach (var boundarySegment in boundarySegments)
{
curveLoop.Append(boundarySegment.GetCurve());
}
curveLoops.Add(curveLoop);
}
}
doc.Invoke(
_ =>
{
//double angle = 0;
var array = GetFaceArray(doc, curveLoops, out var ds);
var curtainSystemType = SetCurtainSystemType(doc, length, width, gap, thickness, panelName);
var curtainSystem = doc.Create.NewCurtainSystem(array, curtainSystemType);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ANGLE_1).Set(0);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ANGLE_2).Set(0);
curtainSystem.get_Parameter(BuiltInParameter.SPACING_JUSTIFICATION_1).Set(2);
curtainSystem.get_Parameter(BuiltInParameter.SPACING_JUSTIFICATION_2).Set(2);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ORIGIN_1).Set(0);
curtainSystem.get_Parameter(BuiltInParameter.CURTAINGRID_ORIGIN_2).Set(0);
if (ds != null)
{
doc.Delete(ds.Id);
}
ElementTransformUtils.MoveElement(doc, curtainSystem.Id, XYZ.BasisZ * thickness / 304.8 / 2);
},
"创建铺贴饰面"
);
//CreateCurtainSystem(length, width, gap, thickness, angle, offset, doc, curveLoops, XYZ.BasisZ);
}
[RelayCommand]
private void PlaceBricks()
{
finishesHandler.Raise(uiapp =>
{
var uidoc = uiapp.ActiveUIDocument;
try
{
if (ByRoom)
{
CreateCurtainSystemByRoom(uidoc, PavementLength, PavementWidth, PavementGap, PavementThickness, PanelName);
}
else
{
CreateCurtainSystemByFace(
uidoc,
PavementLength,
PavementWidth,
PavementGap,
PavementThickness,
WallBaseOffset,
PanelName,
IsEdgeExistGap
);
}
}
catch (Autodesk.Revit.Exceptions.OperationCanceledException) { }
});
}
private static XYZ GetOrigin(Document doc, CurtainSystem curtainSystem, out XYZ u, out XYZ v)
{
XYZ origin = null;
var iterator = curtainSystem.CurtainGrids.ForwardIterator();
iterator.MoveNext();
var grid = iterator.Current as CurtainGrid;
var uLineId = grid.GetUGridLineIds().FirstOrDefault();
var vLineId = grid.GetVGridLineIds().FirstOrDefault();
var uLine = doc.GetElement(uLineId) as CurtainGridLine;
var vLine = doc.GetElement(vLineId) as CurtainGridLine;
var l1 = uLine.FullCurve as Line;
u = l1.Direction;
var l2 = vLine.FullCurve as Line;
v = l2.Direction;
var result = l1.Intersect(l2, out var resultArray);
if (result != SetComparisonResult.Disjoint)
{
if (!resultArray.IsEmpty)
{
origin = resultArray.get_Item(0).XYZPoint;
}
}
return origin;
}
}
public class EdgeFilter : ISelectionFilter
{
public EdgeFilter(Element preElement)
{
element = preElement;
}
private readonly Element element;
public bool AllowElement(Element elem)
{
return element.Id == elem.Id;
}
public bool AllowReference(Reference reference, XYZ position)
{
return true;
}
}