IFittingCoordinate.cs 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. using Autodesk.Revit.DB;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.Threading.Tasks;
  7. namespace FWindSoft.Revit.Mep
  8. {
  9. /// <summary>
  10. /// 构件初始坐标接口(匹配connector的连接点)
  11. /// </summary>
  12. public interface IFittingCoordinate
  13. {
  14. /// <summary>
  15. /// 获取指定实例的连接点坐标
  16. /// </summary>
  17. /// <param name="fi"></param>
  18. /// <returns></returns>
  19. Tuple<XYZ, XYZ> GetCoordinate(FamilyInstance fi);
  20. }
  21. /// <summary>
  22. /// 连接件坐标生成工厂
  23. /// </summary>
  24. public static class FittingCoordinateFactory
  25. {
  26. /// <summary>
  27. /// 根据内置分类,获取相应的构件坐标
  28. /// </summary>
  29. /// <param name="builtCategory"></param>
  30. /// <returns></returns>
  31. public static IFittingCoordinate CreateFittingCoordinate(BuiltInCategory builtCategory)
  32. {
  33. if (builtCategory == BuiltInCategory.OST_ConduitFitting)
  34. {
  35. return new ConduitFittingCoordinate();
  36. }
  37. else if (builtCategory == BuiltInCategory.OST_PipeFitting)
  38. {
  39. return new PipeFittingCoordinate();
  40. }
  41. return null;
  42. }
  43. /// <summary>
  44. /// 获取实例的坐标体系
  45. /// </summary>
  46. /// <param name="fi"></param>
  47. /// <returns></returns>
  48. public static Tuple<XYZ, XYZ> GetCoordinate(FamilyInstance fi)
  49. {
  50. var builtCategory = fi.GetBuiltInCategory();
  51. var realFittingCoordinate = CreateFittingCoordinate(builtCategory);
  52. return realFittingCoordinate?.GetCoordinate(fi);
  53. }
  54. }
  55. /// <summary>
  56. /// 线管连接件坐标
  57. /// </summary>
  58. internal class ConduitFittingCoordinate : IFittingCoordinate
  59. {
  60. public Tuple<XYZ, XYZ> GetCoordinate(FamilyInstance fi)
  61. {
  62. return new Tuple<XYZ, XYZ>(XYZ.BasisX, XYZ.BasisY);
  63. }
  64. }
  65. /// <summary>
  66. /// 水管管连接件坐标
  67. /// </summary>
  68. internal class PipeFittingCoordinate : IFittingCoordinate
  69. {
  70. public Tuple<XYZ, XYZ> GetCoordinate(FamilyInstance fi)
  71. {
  72. var connectors = fi.GetConnectors(Domain.DomainPiping);
  73. Connector primaryConnector = connectors.FirstOrDefault(c => c.GetMEPConnectorInfo().IsPrimary);
  74. Connector secondConnector = null;
  75. foreach (Connector connector in connectors)
  76. {
  77. if (connector == primaryConnector)
  78. {
  79. continue;
  80. }
  81. if (!connector.CoordinateSystem.BasisZ.IsParallel(primaryConnector.CoordinateSystem.BasisZ))
  82. {
  83. secondConnector = connector;
  84. break;
  85. }
  86. }
  87. if(primaryConnector==null||secondConnector==null)
  88. {
  89. return null;
  90. }
  91. #region 特殊处理
  92. try
  93. {
  94. if (connectors.Count == 2)
  95. {
  96. secondConnector.Angle = Math.PI / 2;
  97. }
  98. else if (connectors.Count == 3)
  99. {
  100. secondConnector.Angle = Math.PI / 2;
  101. }
  102. }
  103. catch (Exception e)
  104. {
  105. //如果没有参照角可能会发生异常;四通设置90度有问题。设置0度是不是可以?
  106. //throw;
  107. }
  108. #endregion
  109. var firstDirection = primaryConnector.CoordinateSystem.BasisZ;
  110. var secondDirection = secondConnector.CoordinateSystem.BasisZ;
  111. if (!firstDirection.IsVertical(secondDirection))
  112. {
  113. var useSecond = secondDirection - secondDirection.DotProduct(firstDirection) * firstDirection;
  114. secondDirection = useSecond.Normalize();
  115. }
  116. return new Tuple<XYZ, XYZ>(firstDirection, secondDirection);
  117. }
  118. }
  119. }