SpaceManager.cs 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325
  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. public static void DealSpaceFailuresPreprocessor(Document doc, List<FailItem> failItems,FloorSpaceContext context)
  137. {
  138. #region 处理逻辑
  139. /*
  140. * 1、根据条件过滤,满足自动处理的自动处理。
  141. * 2、不满足自动处理的,手动选择保留项
  142. */
  143. #endregion
  144. List<ServerSpace> serverSpaces = new List<ServerSpace>();
  145. Regex regex = new Regex(@"^\d+$");
  146. var index = 1;
  147. foreach (var failItem in failItems)
  148. {
  149. var spacesServerInfo =context.GetPhysicalSpaces(failItem.Select(id=>id.IntegerValue.ToString()).ToList());
  150. if (spacesServerInfo == null || spacesServerInfo.Count == 0)
  151. {
  152. #region 冲突对象不包含物理世界空间
  153. var firstElement = doc.GetElement(failItem.FirstOrDefault());
  154. if (firstElement is RSpace first)
  155. {
  156. for (int i = 1; i < failItem.Count; i++)
  157. {
  158. var currentId = failItem[i];
  159. if (first.Id.IsEqual(currentId))
  160. continue;
  161. var curr = doc.GetElement(currentId) as RSpace;
  162. if (!regex.IsMatch(curr.Number))
  163. {
  164. doc.Delete(new List<ElementId>() { currentId });
  165. continue;
  166. }
  167. if (!regex.IsMatch(first.Number))
  168. {
  169. doc.Delete(new List<ElementId>() { first.Id });
  170. first = curr;
  171. continue;
  172. }
  173. if (int.Parse(first.Number) > int.Parse(curr.Number))
  174. {
  175. doc.Delete(new List<ElementId>() { first.Id });
  176. first = curr;
  177. }
  178. else
  179. {
  180. doc.Delete(new List<ElementId>() { currentId });
  181. }
  182. }
  183. }
  184. #endregion
  185. }
  186. else if (spacesServerInfo.Count == 1)
  187. {
  188. #region 冲突对象包好一个物理世界对象
  189. var serverSpaceId = spacesServerInfo[0].BimID.Split(':')[1];
  190. doc.Delete(failItem.Where(t => t.ToString() != serverSpaceId).ToList());
  191. #endregion
  192. }
  193. else
  194. {
  195. #region 冲突对象包含多个物理世界对象,保留物理世界对象手动选择【一般删掉空间分割产生这种情况】
  196. doc.Delete(failItem.Where(t => !spacesServerInfo.Exists(sp => sp.BimID.Split(':')[1] == t.ToString())).ToList());
  197. var groupName = $"待合并元空间组{index}";
  198. foreach (var mRevitEquipBase in spacesServerInfo)
  199. {
  200. if (mRevitEquipBase is MSpace space)
  201. {
  202. serverSpaces.Add(new ServerSpace()
  203. {
  204. Space = space,
  205. GroupName = groupName
  206. });
  207. }
  208. }
  209. serverSpaces.Add(new ServerSpace()
  210. {
  211. Name = NewCreateSpaceFlag,
  212. GroupName = groupName
  213. });
  214. index++;
  215. #endregion
  216. }
  217. }
  218. if (serverSpaces.Count > 0)
  219. {
  220. var winDeal = new WinSelectSpace(serverSpaces);
  221. var result = winDeal.ShowDialog();
  222. if (result == true)
  223. {
  224. //在指定位置创建空间,保留任意存在空间的定位点,根据定位点创建空间。
  225. var groups = serverSpaces.GroupBy(t => t.GroupName);
  226. List<string> deletedIds = new List<string>();
  227. List<UV> newSpaceLocations = new List<UV>();
  228. foreach (var groupSpaces in groups)
  229. {
  230. var spaces = groupSpaces.ToList();
  231. foreach (var serverSpace in spaces)
  232. {
  233. if (serverSpace.IsChecked)
  234. {
  235. if (IsNewSpaceFlag(serverSpace))
  236. {
  237. //新建标志的,利用原始空间坐标创建新空间
  238. var tempSpace = spaces.FirstOrDefault(c => !IsNewSpaceFlag(c));
  239. var elementId = GetElementId(tempSpace.Space);
  240. var useSpace = doc.GetElement(new ElementId(elementId.ToInt())) as RSpace;
  241. newSpaceLocations.Add(useSpace.GetLocationPoint().ToUv());
  242. }
  243. }
  244. else
  245. {
  246. //没选中删除
  247. if (!IsNewSpaceFlag(serverSpace))
  248. {
  249. deletedIds.Add(GetElementId(serverSpace.Space));
  250. }
  251. }
  252. }
  253. }
  254. #region revit 模型处理
  255. //删除
  256. if (deletedIds.Any())
  257. {
  258. doc.Delete(deletedIds.Select(c=>new ElementId(c.ToInt())).ToList());
  259. }
  260. //创建新的空间
  261. var view = doc.GetUseView();
  262. Phase phase = view.GetParameterElement(BuiltInParameter.VIEW_PHASE) as Phase;
  263. foreach (var newSpaceLocation in newSpaceLocations)
  264. {
  265. var space = ExternalDataWrapper.Current.DocCreater.NewSpace(view.GenLevel, phase,newSpaceLocation);
  266. ExternalDataWrapper.Current.DocCreater.NewSpaceTag(space, newSpaceLocation, view);
  267. }
  268. #endregion
  269. }
  270. else
  271. {
  272. //没处理会有什么操作
  273. }
  274. }
  275. }
  276. /// <summary>
  277. /// 上传模型
  278. /// </summary>
  279. /// <param name="doc"></param>
  280. public static void UploadModel(Document doc)
  281. {
  282. //doc.Save();
  283. string str = "";
  284. UploadModeCommand command = new UploadModeCommand();
  285. command.Execute(null, ref str, null);
  286. }
  287. }
  288. /// <summary>
  289. /// 空间分割信息
  290. /// </summary>
  291. public class SpaceSeparation
  292. {
  293. public SpaceSeparation(XYZ start, XYZ end)
  294. {
  295. this.Start = start;
  296. this.End = end;
  297. }
  298. public XYZ Start { get; private set; }
  299. public XYZ End { get; private set; }
  300. /// <summary>
  301. /// 关联Id
  302. /// </summary>
  303. public int Id { get; set; }
  304. }
  305. }