RevitUtil.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:RevitUtil
  3. * 作者:xulisong
  4. * 创建时间: 2019/6/24 9:55:09
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using Autodesk.Revit.DB;
  8. using SAGA.RevitUtils.Extends;
  9. using SAGA.RevitUtils.Extends.Graphic;
  10. using System;
  11. using System.Collections.Generic;
  12. using System.Linq;
  13. using System.Text;
  14. using System.Threading.Tasks;
  15. using Autodesk.Revit.DB.Mechanical;
  16. using RevitToJBim.Extension;
  17. using RevitToJBim.MBI;
  18. using SAGA.DotNetUtils;
  19. using Parameter = JBIM.Component.Parameter;
  20. using SAGA.RevitUtils;
  21. using SAGA.DotNetUtils.Extend;
  22. using System.Configuration;
  23. namespace RevitToJBim.Common
  24. {
  25. public class RevitUtil
  26. {
  27. /// <summary>
  28. /// 获取FamilyInstance顶面轮廓
  29. /// </summary>
  30. /// <param name="fi"></param>
  31. /// <returns></returns>
  32. public static List<XYZ> GetTopPolygon(FamilyInstance fi)
  33. {
  34. List<XYZ> path = new List<XYZ>();
  35. var faces = fi.GetOriginalFaces(XYZ.BasisZ);
  36. var topface = faces.FirstOrDefault();
  37. //传递的path中没有重复点
  38. if (topface != null)
  39. {
  40. var curves = topface.GetCurves();
  41. for (int i = 0; i < curves.Count; i++)
  42. {
  43. var current = curves[i];
  44. var points = current.GetPoints();
  45. points.RemoveAt(points.Count - 1);
  46. path.AddRange(points);
  47. }
  48. }
  49. return path;
  50. }
  51. /// <summary>
  52. /// 获取FamilyInstance box底面轮廓
  53. /// </summary>
  54. /// <param name="fi"></param>
  55. /// <returns></returns>
  56. public static List<XYZ> GetBottomPolygon(FamilyInstance fi)
  57. {
  58. List<XYZ> path = new List<XYZ>();
  59. try
  60. {
  61. var box = fi.get_BoundingBox(null);
  62. if (box == null) return path;
  63. var boxMin = box.Min;
  64. var boxMax = box.Max;
  65. path.Add(boxMin);
  66. path.Add(boxMin.NewX(boxMax.X));
  67. path.Add(boxMin.NewX(boxMax.X).NewY(boxMax.Y));
  68. path.Add(boxMin.NewY(boxMax.Y));
  69. path.Add(boxMin);
  70. }
  71. catch (Exception e)
  72. {
  73. Console.WriteLine(e);
  74. }
  75. return path;
  76. }
  77. /// <summary>
  78. /// 获取参数
  79. /// </summary>
  80. /// <param name="ele"></param>
  81. /// <param name="parameterNames"></param>
  82. /// <param name="hasEquipComponentCode"></param>
  83. /// <returns></returns>
  84. public static List<Parameter> GetParameters(Element ele, List<string> parameterNames, bool hasEquipComponentCode = false)
  85. {
  86. List<Parameter> parameters = new List<Parameter>();
  87. foreach (var parameterName in parameterNames)
  88. {
  89. var revitParameter = ele.GetParameter(parameterName);
  90. if (revitParameter != null)
  91. {
  92. var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName));
  93. parameter.Value = revitParameter.AsString();
  94. parameters.Add(parameter);
  95. }
  96. }
  97. if (hasEquipComponentCode)
  98. {
  99. var equipComponentCode = ConfigurationManager.AppSettings["EquipComponentCode"];
  100. var typeParameter = ele?.GetElementType()?.Parameters;
  101. foreach (Autodesk.Revit.DB.Parameter p in typeParameter)
  102. {
  103. if (equipComponentCode.Equals(p.Definition.Name))
  104. {
  105. if (!p.HasValue || (p.AsString() == null && p.AsString().Length == 0)) continue;
  106. var parameter = new Parameter(ParameterUtil.FindParameterDefine(equipComponentCode));
  107. parameter.Value = p.AsString();
  108. parameters.Add(parameter);
  109. }
  110. }
  111. }
  112. return parameters;
  113. }
  114. /// <summary>
  115. /// 获取设备设施的参数
  116. /// </summary>
  117. /// <param name="fi"></param>
  118. /// <returns></returns>
  119. public static List<Parameter> GetFacilityParameters(FamilyInstance fi)
  120. {
  121. List<string> parameterNames = ConfigurationManager.AppSettings["FacilityParameters"].Split(',').ToList();
  122. List<Parameter> parameters = GetParameters(fi, parameterNames, true);
  123. return parameters;
  124. }
  125. /// <summary>
  126. /// 获取空间的参数
  127. /// </summary>
  128. /// <param name="space"></param>
  129. /// <returns></returns>
  130. public static List<Parameter> GetSpaceParameters(Element space)
  131. {
  132. List<string> parameterNames = ConfigurationManager.AppSettings["SpaceParameters"].Split(',').ToList();
  133. List<Parameter> parameters = GetParameters(space, parameterNames, false);
  134. return parameters;
  135. }
  136. /// <summary>
  137. /// 获取房间的参数
  138. /// </summary>
  139. /// <param name="room"></param>
  140. /// <returns></returns>
  141. public static List<Parameter> GetRoomParameters(Element room)
  142. {
  143. List<string> parameterNames = ConfigurationManager.AppSettings["RoomParameters"].Split(',').ToList();
  144. List<Parameter> parameters = GetParameters(room, parameterNames, false);
  145. return parameters;
  146. }
  147. /// <summary>
  148. /// 获取设备设施的参数
  149. /// </summary>
  150. /// <param name="space"></param>
  151. /// <returns></returns>
  152. public static List<Parameter> GetMEPCurveParameters(MEPCurve curve)
  153. {
  154. List<string> parameterNames = ConfigurationManager.AppSettings["MEPCurveParameters"].Split(',').ToList();
  155. List<Parameter> parameters = GetParameters(curve, parameterNames, false);
  156. return parameters;
  157. }
  158. /// <summary>
  159. /// 获取部件所关联的设备
  160. /// </summary>
  161. /// <param name="element"></param>
  162. /// <returns></returns>
  163. public static Element GetEquipPartParent(Element element)
  164. {
  165. if (!element.IsEquipmentPart()) return null;
  166. string code = element.GetFamilyName()?.Substring(0, 4); ;
  167. if (code.IsNullOrEmpty()) return null;
  168. //构件所关联的设备
  169. var parentInst = element.Document.GetElements(new ElementIntersectsElementFilter(element))
  170. .FirstOrDefault(t => !t.Id.IsEqual(element.Id) && t.GetFamilyCode() == code);
  171. return parentInst;
  172. }
  173. public static ElementType GetElementType(Element element)
  174. {
  175. ElementId id = element.GetTypeId();
  176. if (id != null && id != ElementId.InvalidElementId)
  177. {
  178. Element elementType = element.Document.GetElement(id);
  179. return elementType as ElementType;
  180. }
  181. return null;
  182. }
  183. /// <summary>
  184. /// 获取门窗到墙线上的投影线
  185. /// </summary>
  186. /// <param name="fi"></param>
  187. /// <returns></returns>
  188. public static List<XYZ> GetWindowDoorLocation(FamilyInstance fi)
  189. {
  190. //取几何实体顶点信息,将点到指定方向做投影
  191. List<XYZ> xyzs = GetVertexPoints(fi);
  192. XYZ handDirection = (fi.Host as Wall)?.Orientation;
  193. if (handDirection != null)
  194. {
  195. handDirection = handDirection.CrossProduct(XYZ.BasisZ);
  196. }
  197. else if (handDirection == null)
  198. {
  199. handDirection = fi.HandOrientation;
  200. }
  201. var location = fi.GetLocationPoint();
  202. if (location == null)
  203. {
  204. location = xyzs.FirstOrDefault();
  205. }
  206. double min = 0, max = 0;
  207. XYZ minXYZ = XYZ.Zero, maxXYZ = XYZ.Zero;
  208. for (int i = 0; i < xyzs.Count; i++)
  209. {
  210. var usePoint = xyzs[i];
  211. var refDirection = usePoint - location;
  212. var offset = refDirection.DotProduct(handDirection);
  213. var projectPoint = location.OffsetPoint(handDirection, offset);
  214. #region 初始化逻辑
  215. if (i == 0)
  216. {
  217. minXYZ = maxXYZ = projectPoint;
  218. min = max = offset;
  219. }
  220. #endregion
  221. #region 判定逻辑
  222. else
  223. {
  224. if (offset < min)
  225. {
  226. minXYZ = projectPoint;
  227. min = offset;
  228. continue;
  229. }
  230. if (max < offset)
  231. {
  232. maxXYZ = projectPoint;
  233. max = offset;
  234. continue;
  235. }
  236. }
  237. #endregion
  238. }
  239. return new List<XYZ>() { minXYZ, maxXYZ };
  240. }
  241. /// <summary>
  242. /// 获取元素顶点集合
  243. /// </summary>
  244. /// <returns></returns>
  245. public static List<XYZ> GetVertexPoints(Element element)
  246. {
  247. List<XYZ> xyzs = new List<XYZ>();
  248. //string id = element.Id.ToString();
  249. //var solids = Extension.GeometryElementExtension.GetSolids(element, element.Document.GetUseView());
  250. //foreach (var solid in solids)
  251. //{
  252. // foreach (Edge edge in solid.Edges)
  253. // {
  254. // xyzs.AddRange(edge.Tessellate());
  255. // }
  256. //}
  257. var curves = Extension.GeometryElementExtension.GetGeometryObjects<Curve>(element, element.Document.GetUseView(), true);
  258. foreach (var curve in curves)
  259. {
  260. xyzs.AddRange(curve.Tessellate());
  261. }
  262. return xyzs.Distinct(new XyzEqualComparer()).ToList();
  263. }
  264. /// <summary>
  265. /// 获取墙的轮廓线
  266. /// </summary>
  267. /// <param name="wall"></param>
  268. /// <returns></returns>
  269. public static List<List<XYZ>> GetWallPolygon(Wall wall)
  270. {
  271. /* 方案1:
  272. * 1找到墙的定位线,
  273. * 2将定位线拆分成多段
  274. * 3按照宽度,将多段定位线生成闭合区域
  275. * 方案2:
  276. * 直接去墙的顶面,过滤相关face形成轮廓
  277. */
  278. List<List<XYZ>> polygons = new List<List<XYZ>>();
  279. #region 过滤墙的顶面
  280. List<PlanarFace> faces = wall.GetBottomFaces();
  281. #endregion
  282. foreach (PlanarFace face in faces)
  283. {
  284. foreach (CurveLoop curveLoop in face.GetEdgesAsCurveLoops())
  285. {
  286. if (curveLoop == null)
  287. {
  288. continue;
  289. }
  290. var polygon = curveLoop.GetPolygon();
  291. if (polygon.Any())
  292. {
  293. polygons.Add(polygon);
  294. }
  295. }
  296. }
  297. return polygons;
  298. }
  299. }
  300. }