RevitUtil.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  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="fi"></param>
  80. /// <returns></returns>
  81. public static List<Parameter> GetFacilityParameters(FamilyInstance fi)
  82. {
  83. List<string> parameterNames=new List<string>(){ MBIBuiltInParameterName.EquipLocalName,MBIBuiltInParameterName.EquipLocalID,MBIBuiltInParameterName.PropertyID };
  84. List<Parameter> parameters=new List<Parameter>();
  85. foreach (var parameterName in parameterNames)
  86. {
  87. var revitParameter = fi.GetParameter(parameterName);
  88. if (revitParameter != null)
  89. {
  90. var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName));
  91. parameter.Value = revitParameter.AsString();
  92. parameters.Add(parameter);
  93. }
  94. }
  95. return parameters;
  96. }
  97. /// <summary>
  98. /// 获取设备设施的参数
  99. /// </summary>
  100. /// <param name="space"></param>
  101. /// <returns></returns>
  102. public static List<Parameter> GetSpaceParameters(Space space)
  103. {
  104. List<string> parameterNames = new List<string>() { MBIBuiltInParameterName.SpaceName, MBIBuiltInParameterName.SpaceNumber };
  105. List<Parameter> parameters = new List<Parameter>();
  106. foreach (var parameterName in parameterNames)
  107. {
  108. var revitParameter = space.GetParameter(parameterName);
  109. if (revitParameter != null)
  110. {
  111. var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName));
  112. parameter.Value = revitParameter.AsString();
  113. parameters.Add(parameter);
  114. }
  115. }
  116. return parameters;
  117. }
  118. /// <summary>
  119. /// 获取设备设施的参数
  120. /// </summary>
  121. /// <param name="space"></param>
  122. /// <returns></returns>
  123. public static List<Parameter> GetMEPCurveParameters(MEPCurve curve)
  124. {
  125. List<string> parameterNames = new List<string>() { MBIBuiltInParameterName.MEPCurveComments};
  126. List<Parameter> parameters = new List<Parameter>();
  127. foreach (var parameterName in parameterNames)
  128. {
  129. var revitParameter = curve.GetParameter(parameterName);
  130. if (revitParameter != null)
  131. {
  132. var parameter = new Parameter(ParameterUtil.FindParameterDefine(parameterName));
  133. parameter.Value = revitParameter.AsString();
  134. parameters.Add(parameter);
  135. }
  136. }
  137. return parameters;
  138. }
  139. /// <summary>
  140. /// 获取部件所关联的设备
  141. /// </summary>
  142. /// <param name="element"></param>
  143. /// <returns></returns>
  144. public static Element GetEquipPartParent(Element element)
  145. {
  146. if (!element.IsEquipmentPart()) return null;
  147. string code = element.GetFamilyName()?.Substring(0, 4); ;
  148. if (code.IsNullOrEmpty()) return null;
  149. //构件所关联的设备
  150. var parentInst = element.Document.GetElements(new ElementIntersectsElementFilter(element))
  151. .FirstOrDefault(t => !t.Id.IsEqual(element.Id) && t.GetFamilyCode() == code);
  152. return parentInst;
  153. }
  154. /// <summary>
  155. /// 获取门窗到墙线上的投影线
  156. /// </summary>
  157. /// <param name="fi"></param>
  158. /// <returns></returns>
  159. public static List<XYZ> GetWindowDoorLocation(FamilyInstance fi)
  160. {
  161. //取几何实体顶点信息,将点到指定方向做投影
  162. List<XYZ> xyzs = GetVertexPoints(fi);
  163. XYZ handDirection = (fi.Host as Wall)?.Orientation;
  164. if (handDirection != null)
  165. {
  166. handDirection = handDirection.CrossProduct(XYZ.BasisZ);
  167. }
  168. else if (handDirection == null)
  169. {
  170. handDirection = fi.HandOrientation;
  171. }
  172. var location = fi.GetLocationPoint();
  173. if (location == null)
  174. {
  175. location = xyzs.FirstOrDefault();
  176. }
  177. double min = 0, max = 0;
  178. XYZ minXYZ = XYZ.Zero, maxXYZ = XYZ.Zero;
  179. for (int i = 0; i < xyzs.Count; i++)
  180. {
  181. var usePoint = xyzs[i];
  182. var refDirection = usePoint - location;
  183. var offset = refDirection.DotProduct(handDirection);
  184. var projectPoint = location.OffsetPoint(handDirection, offset);
  185. #region 初始化逻辑
  186. if (i == 0)
  187. {
  188. minXYZ = maxXYZ = projectPoint;
  189. min = max = offset;
  190. }
  191. #endregion
  192. #region 判定逻辑
  193. else
  194. {
  195. if (offset < min)
  196. {
  197. minXYZ = projectPoint;
  198. min = offset;
  199. continue;
  200. }
  201. if (max < offset)
  202. {
  203. maxXYZ = projectPoint;
  204. max = offset;
  205. continue;
  206. }
  207. }
  208. #endregion
  209. }
  210. return new List<XYZ>() { minXYZ, maxXYZ };
  211. }
  212. /// <summary>
  213. /// 获取元素顶点集合
  214. /// </summary>
  215. /// <returns></returns>
  216. public static List<XYZ> GetVertexPoints(Element element)
  217. {
  218. List<XYZ> xyzs = new List<XYZ>();
  219. //string id = element.Id.ToString();
  220. //var solids = Extension.GeometryElementExtension.GetSolids(element, element.Document.GetUseView());
  221. //foreach (var solid in solids)
  222. //{
  223. // foreach (Edge edge in solid.Edges)
  224. // {
  225. // xyzs.AddRange(edge.Tessellate());
  226. // }
  227. //}
  228. var curves= Extension.GeometryElementExtension.GetGeometryObjects<Curve>(element, element.Document.GetUseView(), true);
  229. foreach (var curve in curves)
  230. {
  231. xyzs.AddRange(curve.Tessellate());
  232. }
  233. return xyzs.Distinct(new XyzEqualComparer()).ToList();
  234. }
  235. /// <summary>
  236. /// 获取墙的轮廓线
  237. /// </summary>
  238. /// <param name="wall"></param>
  239. /// <returns></returns>
  240. public static List<List<XYZ>> GetWallPolygon(Wall wall)
  241. {
  242. /* 方案1:
  243. * 1找到墙的定位线,
  244. * 2将定位线拆分成多段
  245. * 3按照宽度,将多段定位线生成闭合区域
  246. * 方案2:
  247. * 直接去墙的顶面,过滤相关face形成轮廓
  248. */
  249. List<List<XYZ>> polygons = new List<List<XYZ>>();
  250. #region 过滤墙的顶面
  251. List<PlanarFace> faces = wall.GetBottomFaces();
  252. #endregion
  253. foreach (PlanarFace face in faces)
  254. {
  255. foreach (CurveLoop curveLoop in face.GetEdgesAsCurveLoops())
  256. {
  257. if (curveLoop == null)
  258. {
  259. continue;
  260. }
  261. var polygon = curveLoop.GetPolygon();
  262. if (polygon.Any())
  263. {
  264. polygons.Add(polygon);
  265. }
  266. }
  267. }
  268. return polygons;
  269. }
  270. }
  271. }