调整代码
This commit is contained in:
203
ShrlAlgoToolkit.RevitAddins/ArchStru/SlopedFloorCmd.cs
Normal file
203
ShrlAlgoToolkit.RevitAddins/ArchStru/SlopedFloorCmd.cs
Normal file
@@ -0,0 +1,203 @@
|
||||
using Autodesk.Revit.Attributes;
|
||||
using Autodesk.Revit.DB;
|
||||
using Autodesk.Revit.UI.Selection;
|
||||
using Nice3point.Revit.Toolkit.External;
|
||||
|
||||
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.RvCivil;
|
||||
|
||||
[Transaction(TransactionMode.Manual)]
|
||||
public class SlopedFloorCmd : ExternalCommand
|
||||
{
|
||||
public override void Execute()
|
||||
{
|
||||
Document.Invoke(
|
||||
_ =>
|
||||
{
|
||||
Line line1 = null;
|
||||
Line line2 = null;
|
||||
HostObject obj1 = null;
|
||||
HostObject obj2 = null;
|
||||
var refer = UiDocument.Selection.PickObject(
|
||||
ObjectType.Edge,
|
||||
new FuncFilter(
|
||||
elem => elem is HostObject,
|
||||
(r, _) =>
|
||||
{
|
||||
obj1 = Document.GetElement(r) as HostObject;
|
||||
var edge = obj1?.GetGeometryObjectFromReference(r) as Edge;
|
||||
if (edge?.AsCurve() is Line l && l.Direction.Z < 0.0001)
|
||||
{
|
||||
line1 = l;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
),
|
||||
"请选择主体元素其中的一条水平边"
|
||||
);
|
||||
var elem = Document.GetElement(refer);
|
||||
UiDocument.Selection.PickObject(
|
||||
ObjectType.Edge,
|
||||
new FuncFilter(
|
||||
elem => elem is HostObject && elem.Id != obj1.Id,
|
||||
(r, _) =>
|
||||
{
|
||||
obj2 = Document.GetElement(r) as HostObject;
|
||||
|
||||
var edge1 = obj2?.GetGeometryObjectFromReference(r) as Edge;
|
||||
if (
|
||||
edge1?.AsCurve() is Line l
|
||||
&& l.Direction.Z < 0.0001
|
||||
&& l.Direction.CrossProduct(line1.Direction).IsAlmostEqualTo(XYZ.Zero)
|
||||
&& l.Distance(line1.Origin) > Application.ShortCurveTolerance / 304.8
|
||||
)
|
||||
{
|
||||
line2 = l;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
),
|
||||
"请选择与另一条平行的水平边"
|
||||
);
|
||||
var level1 = Document.GetElement(obj1.LevelId) as Level;
|
||||
var level2 = Document.GetElement(obj2.LevelId) as Level;
|
||||
var baseLevel = level1?.Elevation > level2?.Elevation ? level2 : level1;
|
||||
//基准边,低的边
|
||||
var lineBase = line1.Origin.Z < line2.Origin.Z ? line1 : line2;
|
||||
var lineAnother = line1.Origin.Z < line2.Origin.Z ? line2 : line1;
|
||||
//if (line1.Origin.Z < line2.Origin.Z)
|
||||
//{
|
||||
// lineBase = line1;
|
||||
// lineAnother = line2;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// lineBase = line2;
|
||||
// lineAnother = line1;
|
||||
//}
|
||||
|
||||
var curveArr = new CurveArray();
|
||||
var planeToProject = Plane.CreateByNormalAndOrigin(XYZ.BasisZ, lineBase.Origin);
|
||||
var p1 = planeToProject.ProjectOf(lineBase.GetEndPoint(0));
|
||||
var p2 = planeToProject.ProjectOf(lineBase.GetEndPoint(1));
|
||||
var p3 = planeToProject.ProjectOf(lineAnother.GetEndPoint(0));
|
||||
var p4 = planeToProject.ProjectOf(lineAnother.GetEndPoint(1));
|
||||
Line l1;
|
||||
Line l2;
|
||||
Line l3;
|
||||
Line l4;
|
||||
|
||||
if (lineBase.Direction.IsAlmostEqualTo(lineAnother.Direction))
|
||||
{
|
||||
l1 = Line.CreateBound(p1, p2);
|
||||
l3 = Line.CreateBound(p4, p3);
|
||||
l4 = Line.CreateBound(p3, p1);
|
||||
l2 = Line.CreateBound(p2, p4);
|
||||
}
|
||||
else
|
||||
{
|
||||
l1 = Line.CreateBound(p1, p2);
|
||||
l3 = Line.CreateBound(p3, p4);
|
||||
l4 = Line.CreateBound(p4, p1);
|
||||
l2 = Line.CreateBound(p2, p3);
|
||||
}
|
||||
|
||||
curveArr.Append(l1);
|
||||
curveArr.Append(l2);
|
||||
curveArr.Append(l3);
|
||||
curveArr.Append(l4);
|
||||
|
||||
//var isStructure = obj1.get_Parameter(BuiltInParameter.FLOOR_PARAM_IS_STRUCTURAL).AsInteger();
|
||||
//选择线的中点连线
|
||||
var centerLine = Line.CreateBound(lineBase.Evaluate(0.5, true), lineAnother.Evaluate(0.5, true));
|
||||
//中线和边线叉乘,求出楼板面的法向量
|
||||
var floorNormal = lineBase.Direction.CrossProduct(centerLine.Direction);
|
||||
if (floorNormal.Z < 0)
|
||||
{
|
||||
floorNormal = floorNormal.Negate();
|
||||
}
|
||||
|
||||
//坡度角
|
||||
var radian = floorNormal.AngleTo(XYZ.BasisZ);
|
||||
|
||||
//另一条楼板边垂直xy的平面
|
||||
var normal = lineAnother.Direction.CrossProduct(XYZ.BasisZ);
|
||||
var plane = Plane.CreateByNormalAndOrigin(normal, lineAnother.Evaluate(0.5, true));
|
||||
//点与平面的距离
|
||||
var centerPoint = lineBase.Evaluate(0.5, true);
|
||||
var perpPoint = plane.ProjectOf(centerPoint);
|
||||
var slopedArrow = Line.CreateBound(centerPoint, new XYZ(perpPoint.X, perpPoint.Y, centerPoint.Z));
|
||||
//if (lineBase.Origin.Z > lineAnother.Origin.Z)
|
||||
//{
|
||||
// slopedArrow = slopedArrow.CreateReversed() as Line;
|
||||
//}
|
||||
//即板上表面法向量和Z轴正向之间
|
||||
//double radian = slopedArrow.Direction.AngleOnPlaneTo(XYZ.BasisX, XYZ.BasisZ);
|
||||
//double slope = Math.Abs(line1.Evaluate(0.5, true).Z - line2.Evaluate(0.5, true).Z);
|
||||
|
||||
//slopedArrow用以指定在XY平面上绘制的板轮廓,是沿着哪个方向进行坡度变化的。因此,这条线实际上是XY平面上,垂直于板上表面与XY平面交线的一条线。
|
||||
#if REVIT2018 || REVIT2020
|
||||
Document.Create.NewSlab(curveArr, baseLevel, slopedArrow, Math.Tan(radian), true);
|
||||
#elif REVIT2025
|
||||
var floorType = Floor.GetDefaultFloorType(Document, false);
|
||||
if (elem is Floor floor)
|
||||
{
|
||||
floorType = floor.GetTypeId();
|
||||
}
|
||||
var loops = new List<CurveLoop>() { CurveLoop.Create(new List<Curve>() { l1, l2, l3, l4 }) };
|
||||
Floor.Create(Document, loops, floorType, baseLevel.Id, true, slopedArrow, Math.Tan(radian));
|
||||
#endif
|
||||
},
|
||||
"坡度楼板"
|
||||
);
|
||||
}
|
||||
|
||||
private static bool IfSameHeight(List<double> vs)
|
||||
{
|
||||
//判断楼板中各端点标高是否相等
|
||||
List<double> list = new();
|
||||
foreach (var z in vs)
|
||||
{
|
||||
if (list.Contains(z) == false)
|
||||
{
|
||||
list.Add(z);
|
||||
}
|
||||
}
|
||||
|
||||
return list.Count == 1;
|
||||
}
|
||||
|
||||
//编辑子图元
|
||||
private void EditSubElements(Floor floor)
|
||||
{
|
||||
#if REVIT2018 || REVIT2020
|
||||
var slabShapeEditor = floor.SlabShapeEditor;
|
||||
#elif REVIT2025
|
||||
var slabShapeEditor = floor.GetSlabShapeEditor();
|
||||
#endif
|
||||
if (slabShapeEditor.IsEnabled)
|
||||
{
|
||||
var vertices = slabShapeEditor.SlabShapeVertices;
|
||||
var zList = new List<double>();
|
||||
foreach (SlabShapeVertex slabShapeVertex in vertices)
|
||||
{
|
||||
zList.Add(slabShapeVertex.Position.Z);
|
||||
}
|
||||
|
||||
//判断为水平板后重设形状
|
||||
if (IfSameHeight(zList))
|
||||
{
|
||||
var floorLevel = floor.Document.GetElement(floor.LevelId) as Level; //获取楼板所在标高
|
||||
var levelHeight = floorLevel.LookupParameter("立面").AsDouble(); //获取所在标高的标高
|
||||
var offsetHeight = zList.FirstOrDefault() - levelHeight;
|
||||
floor.get_Parameter(BuiltInParameter.FLOOR_HEIGHTABOVELEVEL_PARAM).Set(offsetHeight);
|
||||
slabShapeEditor.ResetSlabShape();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user