ElementRangeCheck.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327
  1. /* ==============================================================================
  2. * 功能描述:构件范围检查
  3. * 创 建 者:Garrett
  4. * 创建日期:2018/10/23 15:08:55
  5. * ==============================================================================*/
  6. using System;
  7. using System.Collections.Generic;
  8. using System.Linq;
  9. using System.Text.RegularExpressions;
  10. using Autodesk.Revit.DB;
  11. using Autodesk.Revit.DB.Mechanical;
  12. using NPOI.SS.UserModel;
  13. using SAGA.DotNetUtils.Extend;
  14. using SAGA.DotNetUtils.Others;
  15. using SAGA.MBI.Tools;
  16. using SAGA.MBI.ToolsData.CheckBase;
  17. using SAGA.RevitUtils.Extends;
  18. using NPOI.SS.Util;
  19. using NPOI.XSSF.UserModel;
  20. namespace SAGA.MBI.ToolsData.ModeCheck
  21. {
  22. /// <summary>
  23. ///
  24. /// </summary>
  25. class ElementRangeCheck : ModeCheckBase
  26. {
  27. public ElementRangeCheck()
  28. {
  29. Name = "构件范围检查";
  30. }
  31. [DataCheckProcessAspect]
  32. public override bool Check()
  33. {
  34. if (!RBase.IsRight)
  35. {
  36. IsRight = RBase.IsRight;
  37. return IsRight;
  38. }
  39. IsRight = GetCheckResult();
  40. return IsRight;
  41. }
  42. public override void Correct()
  43. {
  44. throw new NotImplementedException();
  45. }
  46. #region CheckMethod
  47. private bool GetCheckResult()
  48. {
  49. bool unitResult = true;
  50. foreach (SagaSignCheckResult signResult in RBase.Results)
  51. {
  52. CheckCurrentFloor(signResult);
  53. }
  54. return Results.All(t => t.IsRight);
  55. }
  56. /// <summary>
  57. /// 检查当前层
  58. /// </summary>
  59. /// <param name="signResult"></param>
  60. private void CheckCurrentFloor(SagaSignCheckResult signResult)
  61. {
  62. var document = signResult.RDocument;
  63. if (SetFloorBaseTopRange(document, signResult))
  64. {
  65. var elements = document.GetAllElements();
  66. foreach (var element in elements)
  67. {
  68. var result = GetCheckResult(signResult, element);
  69. if (result != null)
  70. Results.Add(result);
  71. }
  72. }
  73. CalcRCPassRate(signResult);
  74. }
  75. /// <summary>
  76. /// 计算本层构件范围检查通过率
  77. /// </summary>
  78. private void CalcRCPassRate(SagaSignCheckResult signResult)
  79. {
  80. Func<Func<ModeCheckResultBase, bool>, double> rateFunc = (condition) =>
  81. {
  82. double passRate = 1;
  83. var items = Results.Where(condition);
  84. int count = items.Count();
  85. if (count > 0)
  86. {
  87. var passItems = items.Where(t => t.IsRight);
  88. var passCount = passItems.Count();
  89. passRate = (1.0 * passCount / count);
  90. }
  91. return passRate;
  92. };
  93. //var items = Results.Where(t => t.RBase == signResult);
  94. //int count = items.Count();
  95. //if (count > 0)
  96. //{
  97. // var passItems = items.Where(t => t.IsRight);
  98. // var passCount = passItems.Count();
  99. // passRate = (1.0 * passCount / count);
  100. //}
  101. signResult.RCPassRate = rateFunc((t) => t.RBase == signResult);
  102. signResult.ColumnWallPassRate = rateFunc((t) => new List<DCElementType>() { DCElementType.Wall, DCElementType.Column }.Contains(((ElementRangeCheckResult)t).RType));
  103. signResult.SpacePassRate = rateFunc((t) => ((ElementRangeCheckResult)t).RType == DCElementType.Space);
  104. signResult.InstPassRate = rateFunc((t) => new List<DCElementType>() { DCElementType.Equipment, DCElementType.EuipmentPart, DCElementType.Beacon }.Contains(((ElementRangeCheckResult)t).RType));
  105. }
  106. /// <summary>
  107. /// 设置当前楼层底部和顶部范围
  108. /// </summary>
  109. /// <param name="doc"></param>
  110. /// <param name="result"></param>
  111. private bool SetFloorBaseTopRange(Document doc, SagaSignCheckResult result)
  112. {
  113. bool rt = true;
  114. try
  115. {
  116. //设置楼层底部高度
  117. var curLevelName = result.RFloorName;
  118. //设置楼层顶部高度
  119. if (curLevelName == "RF" || curLevelName == "RFM")
  120. {
  121. result.HTop = double.MaxValue;
  122. result.HSamdwich = double.MaxValue;
  123. }
  124. else
  125. {
  126. var levels = doc.GetLevels();
  127. var mbiLevels = levels.Where(t => Regex.IsMatch(t.Name, @"([BF][1-9]\d*M?|RFM?)"));
  128. var topLevel = mbiLevels.FirstOrDefault(t => t.Elevation.IsThan(result.HBase));
  129. if (topLevel == null)
  130. {
  131. throw new Exception($"标高编码不合法:{curLevelName}不应该是顶层,缺少标高RF或标高RF标注的位置不正确");
  132. }
  133. double nextL = topLevel.Elevation;
  134. string tempTopLevelName = topLevel.Name;
  135. //如果是夹层,获取夹层的上一层
  136. if (Regex.IsMatch(tempTopLevelName, @"([BF][1-9]\d*M|RFM)"))
  137. {
  138. result.HSamdwich = nextL;
  139. topLevel = mbiLevels.FirstOrDefault(t => t.Elevation.IsThan(nextL));
  140. if (topLevel == null)
  141. {
  142. throw new Exception($"标高编码不合法:{tempTopLevelName}不应该是顶层,缺少标高RF或标高RF标注的位置不正确");
  143. }
  144. else
  145. {
  146. result.HTop = topLevel.Elevation;
  147. }
  148. }
  149. else
  150. {
  151. result.HSamdwich = nextL;
  152. result.HTop = nextL;
  153. }
  154. }
  155. }
  156. catch (Exception e)
  157. {
  158. Console.WriteLine(e);
  159. rt = false;
  160. }
  161. return rt;
  162. }
  163. /// <summary>
  164. /// 获取检测结果
  165. /// </summary>
  166. /// <param name="element"></param>
  167. /// <returns></returns>
  168. private ModeCheckResultBase GetCheckResult(SagaSignCheckResult signResult, Element element)
  169. {
  170. var result = new ElementRangeCheckResult();
  171. result.RBase = signResult;
  172. result.FamilyName = element.GetFamily()?.Name;
  173. result.Id = element.Id.ToString();
  174. try
  175. {
  176. double hb = signResult.HBase;
  177. double ht = signResult.HTop;
  178. double hjc = signResult.HSamdwich;
  179. //使用时,单位转化为英寸
  180. double w = signResult.Redundant.ToApi();
  181. double zb = 0, zt = 0;
  182. bool rb = false, rt = false;
  183. bool isBoxInst = false;
  184. if (element is Wall wall)
  185. {
  186. isBoxInst = true;
  187. result.RType = DCElementType.Wall;
  188. zb = wall.GetBaseStaticHeight();
  189. zt = wall.GetTopStaticHeight();
  190. }
  191. else if (element is FamilyInstance fi)
  192. {
  193. if (fi.IsAllColumn())
  194. {
  195. isBoxInst = true;
  196. result.RType = DCElementType.Column;
  197. zb = fi.GetBaseStaticHeight();
  198. zt = fi.GetTopStaticHeight();
  199. }
  200. else if (fi.IsEquipment() || fi.IsEquipmentPart() || fi.IsBeacon())
  201. {
  202. result.RType = GetRType(fi);
  203. zb = fi.GetLocationPointMBIXYZ().Z;
  204. rb = zb.IsBetween(hb, ht);
  205. result.IsRight = rb;
  206. result.RMessage = result.IsRight ? "" : "构件范围不满足要求;请检查构件位置";
  207. }
  208. else
  209. {
  210. result = null;
  211. }
  212. }
  213. else if (element.IsSpace())
  214. {
  215. var space = element as Space;
  216. isBoxInst = true;
  217. result.RType = DCElementType.Space;
  218. zb = space.GetBaseStaticHeight();
  219. zt = space.GetTopStaticHeight();
  220. }
  221. else
  222. {
  223. result = null;
  224. }
  225. if (isBoxInst)
  226. {
  227. rb = zb.IsBetween(hb - w, hb);
  228. rt = zt.IsBetween(ht - w, ht) || zt.IsBetween(hjc - w, hjc);
  229. result.IsRight = rb && rt;
  230. string ttip = rb ? "" : "底部";
  231. string ttop = rt ? "" : rb ? "和顶部" : "顶部";
  232. result.RMessage = result.IsRight ? "" : $"构件范围不满足要求;请检查构件{ttip}{ttop}";
  233. }
  234. }
  235. catch (Exception e)
  236. {
  237. //MessageShowBase.Show(e);
  238. if (result != null)
  239. {
  240. result.IsRight = false;
  241. result.RMessage = result.IsRight ? "" : "构件范围不满足要求;请检查构件底部和顶部";
  242. }
  243. }
  244. return result;
  245. }
  246. /// <summary>
  247. /// 获取构件类型
  248. /// </summary>
  249. /// <param name="fi"></param>
  250. /// <returns></returns>
  251. private DCElementType GetRType(FamilyInstance fi)
  252. {
  253. DCElementType name = DCElementType.None;
  254. if (fi.IsEquipment())
  255. {
  256. name = DCElementType.Equipment;
  257. }
  258. else if (fi.IsEquipmentPart())
  259. {
  260. name = DCElementType.EuipmentPart;
  261. }
  262. else if (fi.IsBeacon())
  263. {
  264. name = DCElementType.Beacon;
  265. }
  266. return name;
  267. }
  268. #endregion
  269. //[DataCheckProcessAspect]
  270. public override void Export()
  271. {
  272. // Check();
  273. try
  274. {
  275. IWorkbook book = DCRExport.GetWorkbook();
  276. //ISheet sheet = book.CreateSheet(Name);
  277. ISheet sheet = book.GetSheet(Name);
  278. #region 添加数据
  279. int index = 4;
  280. //添加 共检查XXX条数据,未通过检查的如下 提示
  281. IRow rowTip = sheet.CreateRow(index - 1);
  282. rowTip.AddCell(0, $"总检查{Results.Count}条数据,未通过检查的如下", DataCheckNPOIStyle.Title);
  283. foreach (ElementRangeCheckResult result in Results)
  284. {
  285. SagaSignCheckResult rbase = result.RBase as SagaSignCheckResult;
  286. if (rbase == null)
  287. continue;
  288. //数量过多,只显示有问题的
  289. if (result.IsRight) continue;
  290. index++;
  291. IRow rowN = sheet.CreateRow(index);
  292. DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
  293. rowN.AddCell(0, rbase.RFloorName, style);
  294. rowN.AddCell(1, rbase.RFileName, style);
  295. rowN.AddCell(2, rbase.RPath, style);
  296. rowN.AddCell(3, result.FamilyName, style);
  297. rowN.AddCell(4, result.RType.GetDescription(), style);
  298. rowN.AddCell(5, result.Id, style);
  299. string rowN4 = result.IsRight ? "通过" : "不通过";
  300. rowN.AddCell(6, rowN4, style);
  301. rowN.AddCell(7, result.RMessage, style);
  302. }
  303. #endregion
  304. }
  305. catch (Exception e)
  306. {
  307. MessageShowBase.Show(e);
  308. }
  309. }
  310. }
  311. }