/* ==============================================================================
* 功能描述:SagaCheck
* 创 建 者:Garrett
* 创建日期:2019/6/11 16:09:09
* ==============================================================================*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text.RegularExpressions;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using SAGA.DotNetUtils.Extend;
using ServiceRevitLib.Common;
using SAGA.RevitUtils.Extends;
using ServiceRevitLib.Extend;
namespace ServiceRevitLib.Mode
{
///
/// SagaCheck
///
class ElementRangeCheck : CheckBase
{
#region 序列化属性
private double m_Redundant = 500;
///
/// 高度冗余
///
public double Redundant
{
get { return m_Redundant; }
set { m_Redundant = value; }
}
private double m_baseLevel;
///
/// 底部标高
///
public double BaseLevel
{
get { return m_baseLevel; }
}
private List m_topLevels = new List();
///
/// 顶部标高(夹层可能涉及多个顶)
///
public string TopLevels
{
get { return string.Join(";", m_topLevels); }
}
#endregion
public override void Check()
{
base.Check();
#region
var document = m_Doc;
if (!SetFloorBaseTopRange()) return;
var elements = document.GetAllElements();
foreach (var element in elements)
{
var result = GetCheckResult(element);
if (result != null)
Content.Add(result);
}
#endregion
}
///
/// 设置当前楼层底部和顶部范围
///
///
///
private bool SetFloorBaseTopRange()
{
bool rt = true;
var document = m_Doc;
try
{
var sagaPlans = document.GetElements()
.Where(t => t.ViewType == ViewType.FloorPlan && t.Name.Contains("-saga")).ToList();
var curFloor = sagaPlans.FirstOrDefault();
if (sagaPlans.Count != 1 || curFloor == null)
{
Result = ResultState.Failure;
ResultMsg = "Saga标记不合法,请修正后再进行检查";
return false;
}
//设置楼层底部高度
m_baseLevel = curFloor.GenLevel.Elevation.FromApi().Round(2);
//设置楼层顶部高度
var levels = m_Doc.GetLevels();
var mbiLevels = levels.Where(t => Regex.IsMatch(t.Name, $"{RegexConstPattern.IsMBILevel}") && t.Elevation.IsThan(m_baseLevel)).ToList();
foreach (Level level in mbiLevels)
{
m_topLevels.Add(level.Elevation.FromApi().Round(2));
if (!Regex.IsMatch(level.Name, $"{RegexConstPattern.IsSandwich}"))
{
break;
}
}
//当前层为屋顶或屋顶夹层时,顶部限制设置为正无穷
if (Regex.IsMatch(curFloor.GenLevel.Name, $"{RegexConstPattern.IsRF}|{RegexConstPattern.IsRFM}"))
{
m_topLevels.Add(double.MaxValue);
}
}
catch (Exception e)
{
Console.WriteLine(e);
rt = false;
}
return rt;
}
///
/// 获取检测结果
///
///
///
private ElementRangeCheckResult GetCheckResult(Element element)
{
var result = new ElementRangeCheckResult();
result.Id = element.Id.ToString();
result.FamilyName = element.GetFamilyName();
try
{
double zb = 0, zt = 0;
bool rb = false, rt = false;
//需要识别判定的构件
DCElementType type = DCElementType.None;
bool isBoxInst = false;
if (element is Wall wall)
{
isBoxInst = true;
zb = wall.GetBaseStaticHeight();
zt = wall.GetTopStaticHeight();
type = DCElementType.Wall;
}
else if (element.IsSpace())
{
var space = element as Space;
isBoxInst = true;
zb = space.GetBaseStaticHeight();
zt = space.GetTopStaticHeight();
type = DCElementType.Space;
}
else if (element is FamilyInstance)
{
if (element.IsAllColumn())
{
var fi = element as FamilyInstance;
isBoxInst = true;
zb = fi.GetBaseStaticHeight();
zt = fi.GetTopStaticHeight();
type = DCElementType.Column;
}
else if (element.IsEquipment() || element.IsEquipmentPart() || element.IsBeacon())
{
zb = element.GetLocationPointMBIXYZ().Z;
type = GetRType(element);
}
}
if (type==DCElementType.None) return null;
//冗余,使用时,统一使用单位mm
double w = Redundant;
zb = zb.FromApi().Round(2);
zt = zt.FromApi().Round(2);
//构件类型
result.Type = type.GetDescription();
if (isBoxInst)
{
rb = zb.IsBetween(m_baseLevel - w, m_baseLevel);
rt = m_topLevels.Any(t => zt.IsBetween(t - w, t));
string ttip = rb ? "" : "底部";
string ttop = rt ? "" : rb ? "和顶部" : "顶部";
result.HeightRange = $"{zb},{zt}";
result.Result = (rb && rt)?ResultState.Success:ResultState.Failure;
result.ResultMsg = rb && rt ? "" : $"构件范围不满足要求;请检查构件{ttip}{ttop}";
}
else
{
rb = m_topLevels.Any(t => zb.IsBetween(m_baseLevel, t));
result.HeightRange = $"{zb}";
result.Result = (rb) ? ResultState.Success : ResultState.Failure;
result.ResultMsg = rb? "" : $"构件范围不满足要求;请检查构件位置";
}
}
catch (Exception e)
{
result.Result = ResultState.Failure;
result.ResultMsg = "构件范围检查异常";
}
return result;
}
///
/// 获取构件类型
///
///
///
private DCElementType GetRType(Element fi)
{
DCElementType name = DCElementType.None;
if (fi.IsEquipment())
{
name = DCElementType.Equipment;
}
else if (fi.IsEquipmentPart())
{
name = DCElementType.EuipmentPart;
}
else if (fi.IsBeacon())
{
name = DCElementType.Beacon;
}
return name;
}
///
/// DCElementType
///
public enum DCElementType
{
[Description("未知")]
None,
[Description("墙")]
Wall,
[Description("柱")]
Column,
[Description("空间")]
Space,
[Description("设备")]
Equipment,
[Description("部件")]
EuipmentPart,
[Description("信标")]
Beacon
}
}
}