RevitUtil.cs 11 KB

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