/* ============================================================================== * 功能描述:构件范围检查 * 创 建 者: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; } } }