using Autodesk.Revit.DB; using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace FWindSoft.Revit.Mep { /// /// 连接件包装 /// public class FittingWrapper { public FittingWrapper(FamilyInstance fi) { Fitting = fi; /* * 当基础的旋转完成。如果Second向量,与Z平行,且需要横放。则将构件进行头部旋转。 * 如果Second向量与Z垂直,且需要竖放时,旋转构件到指定角度 */ } public FamilyInstance Fitting { get; private set; } /// /// 是否能控制摆放 /// public bool CanCtrlPlacement { get; set; } /// /// 摆放样式 /// public int PlacementStyle { get; set; } /// /// 计算Fi的坐标信息,必须是单位向量 /// /// /// public Tuple GetCoordinate(FamilyInstance fi) { var result = FittingCoordinateFactory.GetCoordinate(fi); if (result != null) { return result; } return new Tuple(XYZ.BasisX, XYZ.BasisY); } public void Rotate(XYZ location, XYZ mathFirst, XYZ matchSecond) { bool isRegenerate = false; #region 获取初始坐标 var originCoordinate = GetCoordinate(Fitting); var firstDirection = originCoordinate.Item1; var secondDirection = originCoordinate.Item2; #endregion var doc = Fitting.Document; #region 匹配第一个给定向量 XYZ axisFirst = null; double angleFirst = 0; if (firstDirection.IsParallel(mathFirst)) { if (firstDirection.IsOppositeDirection(mathFirst)) { //反向绕secondDirection,旋转π axisFirst = secondDirection; angleFirst = Math.PI; } } else { axisFirst = firstDirection.CrossProduct(mathFirst).Normalize(); angleFirst = firstDirection.AngleOnPlaneTo(mathFirst, axisFirst); } if (axisFirst != null) { var line = Line.CreateUnbound(location, axisFirst); ElementTransformUtils.RotateElement(doc, Fitting.Id, line, angleFirst); firstDirection = firstDirection.RotateVector(axisFirst, angleFirst); secondDirection = secondDirection.RotateVector(axisFirst, angleFirst); isRegenerate = true; } #endregion #region 匹配第二个给定向量 var baseDirection = firstDirection.Normalize(); var useSecond = matchSecond - matchSecond.DotProduct(baseDirection) * baseDirection; if (!secondDirection.IsSameDirection(useSecond)) { //useSecond与firstDirection垂直,firstDirection 与secondDirection垂直。所以 //useSecond与secondDirection 都与firstDirection。这样他们可以通过旋转得到 var line2 = Line.CreateUnbound(location, baseDirection); var angleSecond = secondDirection.AngleOnPlaneTo(useSecond, baseDirection); ElementTransformUtils.RotateElement(doc, Fitting.Id, line2, angleSecond); isRegenerate = true; } #endregion if (isRegenerate) { Fitting.Document.Regenerate(); } } } }