FittingWrapper.cs 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  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. /// 连接件包装
  11. /// </summary>
  12. public class FittingWrapper
  13. {
  14. public FittingWrapper(FamilyInstance fi)
  15. {
  16. Fitting = fi;
  17. /*
  18. * 当基础的旋转完成。如果Second向量,与Z平行,且需要横放。则将构件进行头部旋转。
  19. * 如果Second向量与Z垂直,且需要竖放时,旋转构件到指定角度
  20. */
  21. }
  22. public FamilyInstance Fitting { get; private set; }
  23. /// <summary>
  24. /// 是否能控制摆放
  25. /// </summary>
  26. public bool CanCtrlPlacement { get; set; }
  27. /// <summary>
  28. /// 摆放样式
  29. /// </summary>
  30. public int PlacementStyle { get; set; }
  31. /// <summary>
  32. /// 计算Fi的坐标信息,必须是单位向量
  33. /// </summary>
  34. /// <param name="fi"></param>
  35. /// <returns></returns>
  36. public Tuple<XYZ, XYZ> GetCoordinate(FamilyInstance fi)
  37. {
  38. var result = FittingCoordinateFactory.GetCoordinate(fi);
  39. if (result != null)
  40. {
  41. return result;
  42. }
  43. return new Tuple<XYZ, XYZ>(XYZ.BasisX, XYZ.BasisY);
  44. }
  45. public void Rotate(XYZ location, XYZ mathFirst, XYZ matchSecond)
  46. {
  47. bool isRegenerate = false;
  48. #region 获取初始坐标
  49. var originCoordinate = GetCoordinate(Fitting);
  50. var firstDirection = originCoordinate.Item1;
  51. var secondDirection = originCoordinate.Item2;
  52. #endregion
  53. var doc = Fitting.Document;
  54. #region 匹配第一个给定向量
  55. XYZ axisFirst = null;
  56. double angleFirst = 0;
  57. if (firstDirection.IsParallel(mathFirst))
  58. {
  59. if (firstDirection.IsOppositeDirection(mathFirst))
  60. {
  61. //反向绕secondDirection,旋转π
  62. axisFirst = secondDirection;
  63. angleFirst = Math.PI;
  64. }
  65. }
  66. else
  67. {
  68. axisFirst = firstDirection.CrossProduct(mathFirst).Normalize();
  69. angleFirst = firstDirection.AngleOnPlaneTo(mathFirst, axisFirst);
  70. }
  71. if (axisFirst != null)
  72. {
  73. var line = Line.CreateUnbound(location, axisFirst);
  74. ElementTransformUtils.RotateElement(doc, Fitting.Id, line, angleFirst);
  75. firstDirection = firstDirection.RotateVector(axisFirst, angleFirst);
  76. secondDirection = secondDirection.RotateVector(axisFirst, angleFirst);
  77. isRegenerate = true;
  78. }
  79. #endregion
  80. #region 匹配第二个给定向量
  81. var baseDirection = firstDirection.Normalize();
  82. var useSecond = matchSecond - matchSecond.DotProduct(baseDirection) * baseDirection;
  83. if (!secondDirection.IsSameDirection(useSecond))
  84. {
  85. //useSecond与firstDirection垂直,firstDirection 与secondDirection垂直。所以
  86. //useSecond与secondDirection 都与firstDirection。这样他们可以通过旋转得到
  87. var line2 = Line.CreateUnbound(location, baseDirection);
  88. var angleSecond = secondDirection.AngleOnPlaneTo(useSecond, baseDirection);
  89. ElementTransformUtils.RotateElement(doc, Fitting.Id, line2, angleSecond);
  90. isRegenerate = true;
  91. }
  92. #endregion
  93. if (isRegenerate)
  94. {
  95. Fitting.Document.Regenerate();
  96. }
  97. }
  98. }
  99. }