/*-------------------------------------------------------------------------
* 功能描述: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;
}
}
}