/*------------------------------------------------------------------------- * 功能描述:RevitUtil * 作者:xulisong * 创建时间: 2019/6/24 9:55:09 * 版本号:v1.0 * -------------------------------------------------------------------------*/ using Autodesk.Revit.DB; using SAGA.RevitUtils.Extends; using SAGA.RevitUtils.Extends.Graphic; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using Autodesk.Revit.DB.Mechanical; using RevitToJBim.Extension; using RevitToJBim.MBI; using SAGA.DotNetUtils; using Parameter=JBIM.Component.Parameter; using SAGA.RevitUtils; using SAGA.DotNetUtils.Extend; namespace RevitToJBim.Common { public class RevitUtil { /// /// 获取FamilyInstance顶面轮廓 /// /// /// public static List GetTopPolygon(FamilyInstance fi) { List path = new List(); var faces = fi.GetOriginalFaces(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; } /// /// 获取FamilyInstance box底面轮廓 /// /// /// public static List GetBottomPolygon(FamilyInstance fi) { List path=new List(); try { 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); } catch (Exception e) { Console.WriteLine(e); } return path; } /// /// 获取设备设施的参数 /// /// /// public static List GetFacilityParameters(FamilyInstance fi) { List parameterNames=new List(){ MBIBuiltInParameterName.EquipLocalName,MBIBuiltInParameterName.EquipLocalID,MBIBuiltInParameterName.PropertyID }; List parameters=new List(); foreach (var parameterName in parameterNames) { var revitParameter = fi.GetParameter(parameterName); if (revitParameter != null) { var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName)); parameter.Value = revitParameter.AsString(); parameters.Add(parameter); } } return parameters; } /// /// 获取设备设施的参数 /// /// /// public static List GetSpaceParameters(Space space) { List parameterNames = new List() { MBIBuiltInParameterName.SpaceName, MBIBuiltInParameterName.SpaceNumber }; List parameters = new List(); foreach (var parameterName in parameterNames) { var revitParameter = space.GetParameter(parameterName); if (revitParameter != null) { var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName)); parameter.Value = revitParameter.AsString(); parameters.Add(parameter); } } return parameters; } /// /// 获取设备设施的参数 /// /// /// public static List GetMEPCurveParameters(MEPCurve curve) { List parameterNames = new List() { MBIBuiltInParameterName.MEPCurveComments}; List parameters = new List(); foreach (var parameterName in parameterNames) { var revitParameter = curve.GetParameter(parameterName); if (revitParameter != null) { var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName)); parameter.Value = revitParameter.AsString(); parameters.Add(parameter); } } return parameters; } /// /// 获取部件所关联的设备 /// /// /// public static Element GetEquipPartParent(Element element) { if (!element.IsEquipmentPart()) return null; string code = element.GetFamilyName()?.Substring(0, 4); ; if (code.IsNullOrEmpty()) return null; //构件所关联的设备 var parentInst = element.Document.GetElements(new ElementIntersectsElementFilter(element)) .FirstOrDefault(t => !t.Id.IsEqual(element.Id) && t.GetFamilyCode() == code); return parentInst; } /// /// 获取门窗到墙线上的投影线 /// /// /// public static List GetWindowDoorLocation(FamilyInstance fi) { //取几何实体顶点信息,将点到指定方向做投影 List xyzs = GetVertexPoints(fi); XYZ handDirection = (fi.Host as Wall)?.Orientation; if (handDirection != null) { handDirection = handDirection.CrossProduct(XYZ.BasisZ); } else if (handDirection == null) { handDirection = fi.HandOrientation; } var location = fi.GetLocationPoint(); if (location == null) { location = xyzs.FirstOrDefault(); } double min = 0, max = 0; XYZ minXYZ = XYZ.Zero, maxXYZ = 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() { minXYZ, maxXYZ }; } /// /// 获取元素顶点集合 /// /// public static List GetVertexPoints(Element element) { List xyzs = new List(); //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= Extension.GeometryElementExtension.GetGeometryObjects(element, element.Document.GetUseView(), true); foreach (var curve in curves) { xyzs.AddRange(curve.Tessellate()); } return xyzs.Distinct(new XyzEqualComparer()).ToList(); } /// /// 获取墙的轮廓线 /// /// /// public static List> GetWallPolygon(Wall wall) { /* 方案1: * 1找到墙的定位线, * 2将定位线拆分成多段 * 3按照宽度,将多段定位线生成闭合区域 * 方案2: * 直接去墙的顶面,过滤相关face形成轮廓 */ List> polygons = new List>(); #region 过滤墙的顶面 List 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; } } }