ElementRangeCheck.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  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 unitResult;
  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.GetLocationPoint().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 is Space space)
  214. {
  215. isBoxInst = true;
  216. result.RType = DCElementType.Space;
  217. zb = space.GetBaseStaticHeight();
  218. zt = space.GetTopStaticHeight();
  219. }
  220. else
  221. {
  222. result = null;
  223. }
  224. if (isBoxInst)
  225. {
  226. rb = zb.IsBetween(hb - w, hb);
  227. rt = zt.IsBetween(ht - w, ht) || zt.IsBetween(hjc - w, hjc);
  228. result.IsRight = rb && rt;
  229. string ttip = rb ? "" : "底部";
  230. string ttop = rt ? "" : rb ? "和顶部" : "顶部";
  231. result.RMessage = result.IsRight ? "" : $"构件范围不满足要求;请检查构件{ttip}{ttop}";
  232. }
  233. }
  234. catch (Exception e)
  235. {
  236. //MessageShowBase.Show(e);
  237. if (result != null)
  238. {
  239. result.IsRight = false;
  240. result.RMessage = result.IsRight ? "" : "构件范围不满足要求;请检查构件底部和顶部";
  241. }
  242. }
  243. return result;
  244. }
  245. /// <summary>
  246. /// 获取构件类型
  247. /// </summary>
  248. /// <param name="fi"></param>
  249. /// <returns></returns>
  250. private DCElementType GetRType(FamilyInstance fi)
  251. {
  252. DCElementType name = DCElementType.None;
  253. if (fi.IsEquipment())
  254. {
  255. name = DCElementType.Equipment;
  256. }
  257. else if (fi.IsEquipmentPart())
  258. {
  259. name = DCElementType.EuipmentPart;
  260. }
  261. else if (fi.IsBeacon())
  262. {
  263. name = DCElementType.Beacon;
  264. }
  265. return name;
  266. }
  267. #endregion
  268. //[DataCheckProcessAspect]
  269. public override void Export()
  270. {
  271. // Check();
  272. try
  273. {
  274. IWorkbook book = DCRExport.GetWorkbook();
  275. //ISheet sheet = book.CreateSheet(Name);
  276. ISheet sheet = book.GetSheet(Name);
  277. #region 添加数据
  278. int index = 4;
  279. //添加 共检查XXX条数据,未通过检查的如下 提示
  280. IRow rowTip = sheet.CreateRow(index - 1);
  281. rowTip.AddCell(0, $"总检查{Results.Count}条数据,未通过检查的如下", DataCheckNPOIStyle.Title);
  282. foreach (ElementRangeCheckResult result in Results)
  283. {
  284. SagaSignCheckResult rbase = result.RBase as SagaSignCheckResult;
  285. if (rbase == null)
  286. continue;
  287. //数量过多,只显示有问题的
  288. if (result.IsRight) continue;
  289. index++;
  290. IRow rowN = sheet.CreateRow(index);
  291. DataCheckNPOIStyle style = result.IsRight ? DataCheckNPOIStyle.Content : DataCheckNPOIStyle.Error;
  292. rowN.AddCell(0, rbase.RFloorName, style);
  293. rowN.AddCell(1, rbase.RFileName, style);
  294. rowN.AddCell(2, rbase.RPath, style);
  295. rowN.AddCell(3, result.FamilyName, style);
  296. rowN.AddCell(4, result.RType.GetDescription(), style);
  297. rowN.AddCell(5, result.Id, style);
  298. string rowN4 = result.IsRight ? "通过" : "不通过";
  299. rowN.AddCell(6, rowN4, style);
  300. rowN.AddCell(7, result.RMessage, style);
  301. }
  302. #endregion
  303. }
  304. catch (Exception e)
  305. {
  306. MessageShowBase.Show(e);
  307. }
  308. }
  309. }
  310. }