|
@@ -0,0 +1,187 @@
|
|
|
+/* ==============================================================================
|
|
|
+ * 功能描述:RevitUtil
|
|
|
+ * 创 建 者:Garrett
|
|
|
+ * 创建日期:2019/10/9 16:03:38
|
|
|
+ * ==============================================================================*/
|
|
|
+using System;
|
|
|
+using System.Collections.Generic;
|
|
|
+using System.Linq;
|
|
|
+using System.Text;
|
|
|
+using System.Threading.Tasks;
|
|
|
+using Autodesk.Revit.DB;
|
|
|
+using SAGA.RevitUtils;
|
|
|
+using SAGA.RevitUtils.Extends;
|
|
|
+using SAGA.RevitUtils.Extends.Graphic;
|
|
|
+using XYZ=Autodesk.Revit.DB.XYZ;
|
|
|
+
|
|
|
+namespace SAGA.MBI.RevitExport.Entity
|
|
|
+{
|
|
|
+ /// <summary>
|
|
|
+ /// RevitUtil
|
|
|
+ /// </summary>
|
|
|
+ public class RevitUtil
|
|
|
+ {
|
|
|
+ /// <summary>
|
|
|
+ /// 获取FamilyInstance顶面轮廓
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fi"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static List<Autodesk.Revit.DB.XYZ> GetTopPolygon(FamilyInstance fi)
|
|
|
+ {
|
|
|
+ List<Autodesk.Revit.DB.XYZ> path = new List<Autodesk.Revit.DB.XYZ>();
|
|
|
+ var faces = fi.GetOriginalFaces(Autodesk.Revit.DB.XYZ.BasisZ);
|
|
|
+ var topface = faces.FirstOrDefault();
|
|
|
+ //传递的path中没有重复点
|
|
|
+ if (topface != null)
|
|
|
+ {
|
|
|
+ var curves = topface.GetCurves();
|
|
|
+ for (int i = 0; i < curves.Count; i++)
|
|
|
+ {
|
|
|
+ var current = curves[i];
|
|
|
+ var points = current.GetPoints();
|
|
|
+ points.RemoveAt(points.Count - 1);
|
|
|
+ path.AddRange(points);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ return path;
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 获取门窗到墙线上的投影线
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fi"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static List<Autodesk.Revit.DB.XYZ> GetWindowDoorLocation(FamilyInstance fi)
|
|
|
+ {
|
|
|
+ //取几何实体顶点信息,将点到指定方向做投影
|
|
|
+ List<Autodesk.Revit.DB.XYZ> xyzs = GetVertexPoints(fi);
|
|
|
+ Autodesk.Revit.DB.XYZ handDirection = (fi.Host as Wall)?.Orientation;
|
|
|
+ if (handDirection != null)
|
|
|
+ {
|
|
|
+ handDirection = handDirection.CrossProduct(Autodesk.Revit.DB.XYZ.BasisZ);
|
|
|
+ }
|
|
|
+ else if (handDirection == null)
|
|
|
+ {
|
|
|
+ handDirection = fi.HandOrientation;
|
|
|
+ }
|
|
|
+ var location = fi.GetLocationPoint();
|
|
|
+ if (location == null)
|
|
|
+ {
|
|
|
+ location = xyzs.FirstOrDefault();
|
|
|
+ }
|
|
|
+
|
|
|
+ double min = 0, max = 0;
|
|
|
+ Autodesk.Revit.DB.XYZ minXYZ = Autodesk.Revit.DB.XYZ.Zero, maxXYZ = Autodesk.Revit.DB.XYZ.Zero;
|
|
|
+ for (int i = 0; i < xyzs.Count; i++)
|
|
|
+ {
|
|
|
+ var usePoint = xyzs[i];
|
|
|
+ var refDirection = usePoint - location;
|
|
|
+ var offset = refDirection.DotProduct(handDirection);
|
|
|
+ var projectPoint = location.OffsetPoint(handDirection, offset);
|
|
|
+ #region 初始化逻辑
|
|
|
+ if (i == 0)
|
|
|
+ {
|
|
|
+ minXYZ = maxXYZ = projectPoint;
|
|
|
+ min = max = offset;
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ #region 判定逻辑
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (offset < min)
|
|
|
+ {
|
|
|
+ minXYZ = projectPoint;
|
|
|
+ min = offset;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if (max < offset)
|
|
|
+ {
|
|
|
+ maxXYZ = projectPoint;
|
|
|
+ max = offset;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ #endregion
|
|
|
+ }
|
|
|
+ return new List<Autodesk.Revit.DB.XYZ>() { minXYZ, maxXYZ };
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 获取FamilyInstance box底面轮廓
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="fi"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static List<Autodesk.Revit.DB.XYZ> GetBottomPolygon(FamilyInstance fi)
|
|
|
+ {
|
|
|
+ List<Autodesk.Revit.DB.XYZ> path = new List<Autodesk.Revit.DB.XYZ>();
|
|
|
+ var box = fi.get_BoundingBox(null);
|
|
|
+ if (box == null) return path;
|
|
|
+ var boxMin = box.Min;
|
|
|
+ var boxMax = box.Max;
|
|
|
+ path.Add(boxMin);
|
|
|
+ path.Add(boxMin.NewX(boxMax.X));
|
|
|
+ path.Add(boxMin.NewX(boxMax.X).NewY(boxMax.Y));
|
|
|
+ path.Add(boxMin.NewY(boxMax.Y));
|
|
|
+ path.Add(boxMin);
|
|
|
+ return path;
|
|
|
+ }
|
|
|
+ /// <summary>
|
|
|
+ /// 获取元素顶点集合
|
|
|
+ /// </summary>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static List<Autodesk.Revit.DB.XYZ> GetVertexPoints(Element element)
|
|
|
+ {
|
|
|
+ List<Autodesk.Revit.DB.XYZ> xyzs = new List<Autodesk.Revit.DB.XYZ>();
|
|
|
+ //string id = element.Id.ToString();
|
|
|
+ //var solids = Extension.GeometryElementExtension.GetSolids(element, element.Document.GetUseView());
|
|
|
+ //foreach (var solid in solids)
|
|
|
+ //{
|
|
|
+ // foreach (Edge edge in solid.Edges)
|
|
|
+ // {
|
|
|
+ // xyzs.AddRange(edge.Tessellate());
|
|
|
+ // }
|
|
|
+ //}
|
|
|
+ var curves = GeometryElementExtension.GetGeometryObjects<Curve>(element, element.Document.GetUseView(), true);
|
|
|
+ foreach (var curve in curves)
|
|
|
+ {
|
|
|
+ xyzs.AddRange(curve.Tessellate());
|
|
|
+ }
|
|
|
+ return xyzs.Distinct(new XyzEqualComparer()).ToList();
|
|
|
+ }
|
|
|
+
|
|
|
+ /// <summary>
|
|
|
+ /// 获取墙的轮廓线
|
|
|
+ /// </summary>
|
|
|
+ /// <param name="wall"></param>
|
|
|
+ /// <returns></returns>
|
|
|
+ public static List<List<Autodesk.Revit.DB.XYZ>> GetWallPolygon(Wall wall)
|
|
|
+ {
|
|
|
+ /* 方案1:
|
|
|
+ * 1找到墙的定位线,
|
|
|
+ * 2将定位线拆分成多段
|
|
|
+ * 3按照宽度,将多段定位线生成闭合区域
|
|
|
+ * 方案2:
|
|
|
+ * 直接去墙的顶面,过滤相关face形成轮廓
|
|
|
+ */
|
|
|
+ List<List<Autodesk.Revit.DB.XYZ>> polygons = new List<List<Autodesk.Revit.DB.XYZ>>();
|
|
|
+ #region 过滤墙的顶面
|
|
|
+ List<PlanarFace> faces = wall.GetBottomFaces();
|
|
|
+ #endregion
|
|
|
+ foreach (PlanarFace face in faces)
|
|
|
+ {
|
|
|
+ foreach (CurveLoop curveLoop in face.GetEdgesAsCurveLoops())
|
|
|
+ {
|
|
|
+ if (curveLoop == null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ var polygon = curveLoop.GetPolygon();
|
|
|
+ if (polygon.Any())
|
|
|
+ {
|
|
|
+ polygons.Add(polygon);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return polygons;
|
|
|
+ }
|
|
|
+ }
|
|
|
+}
|