SpaceManager.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329
  1. /*-------------------------------------------------------------------------
  2. * 功能描述:SpaceManager
  3. * 作者:xulisong
  4. * 创建时间: 2018/12/14 10:11:22
  5. * 版本号:v1.0
  6. * -------------------------------------------------------------------------*/
  7. using System;
  8. using System.Collections.Generic;
  9. using System.Linq;
  10. using System.Text;
  11. using System.Text.RegularExpressions;
  12. using System.Threading.Tasks;
  13. using Autodesk.Revit.DB;
  14. using Autodesk.Revit.DB.Architecture;
  15. using SAGA.DotNetUtils;
  16. using SAGA.MBI.Common;
  17. using SAGA.MBI.Model;
  18. using SAGA.MBI.WinView.Space;
  19. using SAGA.RevitUtils;
  20. using SAGA.RevitUtils.Extends;
  21. using RSpace=Autodesk.Revit.DB.Mechanical.Space;
  22. namespace SAGA.MBI.WinView
  23. {
  24. /// <summary>
  25. /// 元空间管理相关模操作
  26. /// </summary>
  27. public class SpaceManager
  28. {
  29. public const string NewCreateSpaceFlag = "不保留已有空间,创建新空间";
  30. public static bool IsNewSpaceFlag(ServerSpace space)
  31. {
  32. return space?.Name == NewCreateSpaceFlag;
  33. }
  34. /// <summary>
  35. /// 获取元素Id
  36. /// </summary>
  37. /// <param name="space"></param>
  38. /// <returns></returns>
  39. public static string GetElementId(MSpace space)
  40. {
  41. return space.BimID.Split(':')[1];
  42. }
  43. /// <summary>
  44. /// 更新项目中的空间分割
  45. /// </summary>
  46. /// <param name="doc"></param>
  47. /// <param name="separations"></param>
  48. /// <param name="deletedIds"></param>
  49. public static void UpdateSpaceSequaration(Document doc,List<SpaceSeparation> separations,List<int> deletedIds)
  50. {
  51. using (Transaction trans = new Transaction(doc, "更新空间分隔符"))
  52. {
  53. trans.Start();
  54. try
  55. {
  56. FailureHandlingOptions fho = trans.GetFailureHandlingOptions();
  57. //警告不提示,但不捕获冲突空间
  58. fho.SetFailuresPreprocessor(new SpaceFailuresPreprocessor());
  59. trans.SetFailureHandlingOptions(fho);
  60. //读取空间所在视图
  61. var view = doc.GetUseView();
  62. if (view == null)
  63. {
  64. MessageShow.Infomation("无法找到-saga标志的视图");
  65. return;
  66. }
  67. //创建空间分隔符
  68. CreateSpaceSeparation(view, separations);
  69. doc.Delete(deletedIds.Select(id => new ElementId(id)).ToList());
  70. trans.Commit();
  71. }
  72. catch (Exception e)
  73. {
  74. trans.RollBack();
  75. }
  76. }
  77. }
  78. /// <summary>
  79. /// 创建空间分隔符
  80. /// </summary>
  81. /// <param name="view"></param>
  82. /// <param name="separations"></param>
  83. public static void CreateSpaceSeparation(ViewPlan view, List<SpaceSeparation> separations)
  84. {
  85. if (view == null)
  86. return;
  87. double z = view.GenLevel.Elevation;
  88. Document doc = view.Document;
  89. Plane p =Plane.CreateByNormalAndOrigin(view.ViewDirection,XYZ.Zero);
  90. var sp = SketchPlane.Create(doc, p);
  91. foreach (var pair in separations)
  92. {
  93. XYZ start = pair.Start.NewZ(z);
  94. XYZ end = pair.End.NewZ(z);
  95. Line line = null;
  96. try
  97. {
  98. line = start.NewLine(end);
  99. }
  100. catch (Exception e)
  101. {
  102. Console.WriteLine(e.StackTrace);
  103. }
  104. if (line != null)
  105. {
  106. var curveArray = new CurveArray();
  107. curveArray.Append(line);
  108. var newLIneId = doc.Create.NewSpaceBoundaryLines(sp, curveArray, view).get_Item(0).Id;
  109. pair.Id = newLIneId.IntegerValue;
  110. }
  111. }
  112. }
  113. /// <summary>
  114. /// 手动创建空间
  115. /// </summary>
  116. /// <param name="doc"></param>
  117. public static void CreateSpace(Document doc)
  118. {
  119. doc.LoadFamilySymbolExt(MBIConst.SpaceTagFamilyFilePath);
  120. var view = doc.GetUseView();
  121. if (view != null)
  122. {
  123. Parameter para = view.GetParameter(BuiltInParameter.VIEW_PHASE);
  124. ElementId phaseId = para.AsElementId();
  125. var phase = doc.GetElement(phaseId) as Phase;
  126. var level = view.GenLevel;
  127. doc.Create.NewSpaces2(level, phase, view);
  128. }
  129. }
  130. /// <summary>
  131. /// 处理冲突信息
  132. /// </summary>
  133. /// <param name="doc"></param>
  134. /// <param name="failItems"></param>
  135. /// <param name="context">楼层上下文</param>
  136. /// <returns>ture表示处理完成,false表示存在没处理的空间【冲突空间可能未处理】</returns>
  137. public static bool DealSpaceFailuresPreprocessor(Document doc, List<FailItem> failItems,FloorSpaceContext context)
  138. {
  139. bool flag = true;
  140. #region 处理逻辑
  141. /*
  142. * 1、根据条件过滤,满足自动处理的自动处理。
  143. * 2、不满足自动处理的,手动选择保留项
  144. */
  145. #endregion
  146. List<ServerSpace> serverSpaces = new List<ServerSpace>();
  147. Regex regex = new Regex(@"^\d+$");
  148. var index = 1;
  149. foreach (var failItem in failItems)
  150. {
  151. var spacesServerInfo =context.GetPhysicalSpaces(failItem.Select(id=>id.IntegerValue.ToString()).ToList());
  152. if (spacesServerInfo == null || spacesServerInfo.Count == 0)
  153. {
  154. #region 冲突对象不包含物理世界空间
  155. var firstElement = doc.GetElement(failItem.FirstOrDefault());
  156. if (firstElement is RSpace first)
  157. {
  158. for (int i = 1; i < failItem.Count; i++)
  159. {
  160. var currentId = failItem[i];
  161. if (first.Id.IsEqual(currentId))
  162. continue;
  163. var curr = doc.GetElement(currentId) as RSpace;
  164. if (!regex.IsMatch(curr.Number))
  165. {
  166. doc.Delete(new List<ElementId>() { currentId });
  167. continue;
  168. }
  169. if (!regex.IsMatch(first.Number))
  170. {
  171. doc.Delete(new List<ElementId>() { first.Id });
  172. first = curr;
  173. continue;
  174. }
  175. if (int.Parse(first.Number) > int.Parse(curr.Number))
  176. {
  177. doc.Delete(new List<ElementId>() { first.Id });
  178. first = curr;
  179. }
  180. else
  181. {
  182. doc.Delete(new List<ElementId>() { currentId });
  183. }
  184. }
  185. }
  186. #endregion
  187. }
  188. else if (spacesServerInfo.Count == 1)
  189. {
  190. #region 冲突对象包好一个物理世界对象
  191. var serverSpaceId = spacesServerInfo[0].BimID.Split(':')[1];
  192. doc.Delete(failItem.Where(t => t.ToString() != serverSpaceId).ToList());
  193. #endregion
  194. }
  195. else
  196. {
  197. #region 冲突对象包含多个物理世界对象,保留物理世界对象手动选择【一般删掉空间分割产生这种情况】
  198. doc.Delete(failItem.Where(t => !spacesServerInfo.Exists(sp => sp.BimID.Split(':')[1] == t.ToString())).ToList());
  199. var groupName = $"待合并元空间组{index}";
  200. foreach (var mRevitEquipBase in spacesServerInfo)
  201. {
  202. if (mRevitEquipBase is MSpace space)
  203. {
  204. serverSpaces.Add(new ServerSpace()
  205. {
  206. Space = space,
  207. GroupName = groupName
  208. });
  209. }
  210. }
  211. serverSpaces.Add(new ServerSpace()
  212. {
  213. Name = NewCreateSpaceFlag,
  214. GroupName = groupName
  215. });
  216. index++;
  217. #endregion
  218. }
  219. }
  220. if (serverSpaces.Count > 0)
  221. {
  222. var winDeal = new WinSelectSpace(serverSpaces);
  223. var result = winDeal.ShowDialog();
  224. if (result == true)
  225. {
  226. //在指定位置创建空间,保留任意存在空间的定位点,根据定位点创建空间。
  227. var groups = serverSpaces.GroupBy(t => t.GroupName);
  228. List<string> deletedIds = new List<string>();
  229. List<UV> newSpaceLocations = new List<UV>();
  230. foreach (var groupSpaces in groups)
  231. {
  232. var spaces = groupSpaces.ToList();
  233. foreach (var serverSpace in spaces)
  234. {
  235. if (serverSpace.IsChecked)
  236. {
  237. if (IsNewSpaceFlag(serverSpace))
  238. {
  239. //新建标志的,利用原始空间坐标创建新空间
  240. var tempSpace = spaces.FirstOrDefault(c => !IsNewSpaceFlag(c));
  241. var elementId = GetElementId(tempSpace.Space);
  242. var useSpace = doc.GetElement(new ElementId(elementId.ToInt())) as RSpace;
  243. newSpaceLocations.Add(useSpace.GetLocationPoint().ToUv());
  244. }
  245. }
  246. else
  247. {
  248. //没选中删除
  249. if (!IsNewSpaceFlag(serverSpace))
  250. {
  251. deletedIds.Add(GetElementId(serverSpace.Space));
  252. }
  253. }
  254. }
  255. }
  256. #region revit 模型处理
  257. //删除
  258. if (deletedIds.Any())
  259. {
  260. doc.Delete(deletedIds.Select(c=>new ElementId(c.ToInt())).ToList());
  261. }
  262. //创建新的空间
  263. var view = doc.GetUseView();
  264. Phase phase = view.GetParameterElement(BuiltInParameter.VIEW_PHASE) as Phase;
  265. foreach (var newSpaceLocation in newSpaceLocations)
  266. {
  267. var space = ExternalDataWrapper.Current.DocCreater.NewSpace(view.GenLevel, phase,newSpaceLocation);
  268. ExternalDataWrapper.Current.DocCreater.NewSpaceTag(space, newSpaceLocation, view);
  269. }
  270. #endregion
  271. }
  272. else
  273. {
  274. //没处理会有什么操作
  275. flag = false;
  276. }
  277. }
  278. return flag;
  279. }
  280. /// <summary>
  281. /// 上传模型
  282. /// </summary>
  283. /// <param name="doc"></param>
  284. public static void UploadModel(Document doc)
  285. {
  286. //doc.Save();
  287. string str = "";
  288. UploadModeCommand command = new UploadModeCommand();
  289. command.Execute(null, ref str, null);
  290. }
  291. }
  292. /// <summary>
  293. /// 空间分割信息
  294. /// </summary>
  295. public class SpaceSeparation
  296. {
  297. public SpaceSeparation(XYZ start, XYZ end)
  298. {
  299. this.Start = start;
  300. this.End = end;
  301. }
  302. public XYZ Start { get; private set; }
  303. public XYZ End { get; private set; }
  304. /// <summary>
  305. /// 关联Id
  306. /// </summary>
  307. public int Id { get; set; }
  308. }
  309. }