/* ==============================================================================
* 功能描述:构件范围检查
* 创 建 者:Garrett
* 创建日期:2018/10/23 15:08:55
* ==============================================================================*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using NPOI.SS.UserModel;
using SAGA.DotNetUtils.Extend;
using SAGA.DotNetUtils.Others;
using SAGA.RevitUtils.Extends;
namespace Saga.PlugIn.ModelCheck
{
///
///
///
[ParseIndex(Index = 2)]
class ElementRangeCheck : ModeCheckBase
{
public ElementRangeCheck()
{
Name = "构件范围检查";
}
public override bool Check()
{
if (!RBase.IsRight)
{
IsRight = RBase.IsRight;
return IsRight;
}
IsRight = GetCheckResult();
return IsRight;
}
#region CheckMethod
private bool GetCheckResult()
{
bool unitResult = true;
foreach (SagaSignCheckResult signResult in RBase.Results)
{
CheckCurrentFloor(signResult);
}
return Results.All(t => t.IsRight);
}
///
/// 检查当前层
///
///
private void CheckCurrentFloor(SagaSignCheckResult signResult)
{
var document = signResult.RDocument;
if (SetFloorBaseTopRange(document, signResult))
{
var elements = document.GetAllElements();
foreach (var element in elements)
{
var result = GetCheckResult(signResult, element);
if (result != null)
Results.Add(result);
}
}
CalcRCPassRate(signResult);
}
///
/// 计算本层构件范围检查通过率
///
private void CalcRCPassRate(SagaSignCheckResult signResult)
{
Func, double> rateFunc = (condition) =>
{
double passRate = 1;
var items = Results.Where(condition);
int count = items.Count();
if (count > 0)
{
var passItems = items.Where(t => t.IsRight);
var passCount = passItems.Count();
passRate = (1.0 * passCount / count);
}
return passRate;
};
signResult.RCPassRate = rateFunc((t) => t.RBase == signResult);
signResult.ColumnWallPassRate = rateFunc((t) => new List() { DCElementType.Wall, DCElementType.Column }.Contains(((ElementRangeCheckResult)t).RType));
signResult.SpacePassRate = rateFunc((t) => ((ElementRangeCheckResult)t).RType == DCElementType.Space);
signResult.InstPassRate = rateFunc((t) => new List() { DCElementType.Equipment, DCElementType.EuipmentPart, DCElementType.Beacon }.Contains(((ElementRangeCheckResult)t).RType));
}
private double m_HTop = 0;
private double m_HBase = 0;
private List m_HSandwishs=new List();
///
/// 设置当前楼层底部和顶部范围
///
///
///
private bool SetFloorBaseTopRange(Document doc, SagaSignCheckResult result)
{
bool rt = true;
try
{
m_HBase = result.HBase;
m_HSandwishs = new List();
//设置楼层底部高度
var curLevelName = result.RPlanName;
var levels = doc.GetLevels();
var mbiLevels = levels.Where(t => Regex.IsMatch(t.Name, $"{ModelCheckConst.IsMBILevel}")).ToList();
Func isSandwichFunc = (str) => { return Regex.IsMatch(str, $"{ModelCheckConst.IsSandwich}");};
//设置楼层顶部高度
if (curLevelName == "RF")
{
m_HTop = double.MaxValue;
}
else
{
var hightThanBaseLevels=mbiLevels.Where(t => t.Elevation.IsThan(m_HBase));
foreach (Level level in hightThanBaseLevels)
{
m_HTop = level.Elevation;
if(isSandwichFunc(level.Name))
m_HSandwishs.Add(level.Elevation);
else
{
break;
}
}
}
}
catch (Exception e)
{
Console.WriteLine(e);
rt = false;
}
return rt;
}
///
/// 获取检测结果
///
///
///
private ModeCheckResultBase GetCheckResult(SagaSignCheckResult signResult, Element element)
{
var result = new ElementRangeCheckResult();
result.RBase = signResult;
result.FamilyName = element.GetFamily()?.Name;
result.Id = element.Id.ToString();
try
{
double hb = signResult.HBase;
double ht = m_HTop;
//使用时,单位转化为英寸
double w = signResult.Redundant.ToApi();
double zb = 0, zt = 0;
bool rb = false, rt = false;
bool isBoxInst = false;
if (element is Wall wall)
{
isBoxInst = true;
result.RType = DCElementType.Wall;
zb = wall.GetBaseStaticHeight();
zt = wall.GetTopStaticHeight();
}
else if (element is Space space)
{
isBoxInst = true;
result.RType = DCElementType.Space;
zb = space.GetBaseStaticHeight();
zt = space.GetTopStaticHeight();
}
else if(element is FamilyInstance)
{
if (element.IsAllColumn())
{
var fi = element as FamilyInstance;
isBoxInst = true;
result.RType = DCElementType.Column;
zb = fi.GetBaseStaticHeight();
zt = fi.GetTopStaticHeight();
}
else if (element.IsEquipment() || element.IsEquipmentPart() || element.IsBeacon())
{
result.RType = GetRType(element);
zb = element.GetLocationPointMBIXYZ().Z;
rb = zb.IsBetween(hb, ht);
result.IsRight = rb;
result.RMessage = result.IsRight ? "" : "构件范围不满足要求;请检查构件位置";
}
else
{
result = null;
}
}
else
{
result = null;
}
if (isBoxInst)
{
rb = zb.IsBetween(hb - w, hb);
rt = zt.IsBetween(ht - w, ht) || m_HSandwishs.Any(t=>zt.IsBetween(t-w,t));
result.IsRight = rb && rt;
string ttip = rb ? "" : "底部";
string ttop = rt ? "" : rb ? "和顶部" : "顶部";
result.RMessage = result.IsRight ? "" : $"构件范围不满足要求;请检查构件{ttip}{ttop}";
}
}
catch (Exception e)
{
//MessageShowBase.Show(e);
if (result != null)
{
result.IsRight = false;
result.RMessage = result.IsRight ? "" : "构件范围不满足要求;请检查构件底部和顶部";
}
}
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;
}
#endregion
//[DataCheckProcessAspect]
public override void Export()
{
try
{
IWorkbook book = DCRExport.GetWorkbook();
//ISheet sheet = book.CreateSheet(Name);
ISheet sheet = book.GetSheet(Name);
#region 添加数据
int index = 4;
//添加 共检查XXX条数据,未通过检查的如下 提示
IRow rowTip = sheet.CreateRow(index - 1);
rowTip.AddCell(0, $"总检查{Results.Count}条数据,未通过检查的如下", DataCheckNPOIStyle.Title);
foreach (ElementRangeCheckResult result in Results)
{
SagaSignCheckResult rbase = result.RBase as SagaSignCheckResult;
if (rbase == null)
continue;
//数量过多,只显示有问题的
if (result.IsRight) continue;
index++;
IRow rowN = sheet.CreateRow(index);
DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
int j = -1;
rowN.AddCell(++j, result.FamilyName, style);
rowN.AddCell(++j, result.RType.GetDescription(), style);
rowN.AddCell(++j, result.Id, style);
string rowN4 = result.IsRight ? "通过" : "不通过";
rowN.AddCell(++j, rowN4, style);
rowN.AddCell(++j, result.RMessage, style);
}
#endregion
}
catch (Exception e)
{
MessageShowBase.Show(e);
}
}
}
///
/// UnitCheckResult
///
class ElementRangeCheckResult : ModeCheckResultBase
{
public string FamilyName { get; set; }
public string Id { get; set; }
///
/// 构件类型
///
public DCElementType RType { get; set; }
}
}