123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264 |
- using Autodesk.Revit.DB;
- using FWindSoft.Data;
- using FWindSoft.SystemExtensions;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using HorizontalAlign = FWindSoft.Data.HorizontalAlign;
- namespace FWindSoft.Revit.Utils
- {
- public static class ConnectorUtils
- {
- /// <summary>
- ///根据点获取Connector
- /// </summary>
- /// <param name="connectors"></param>
- /// <param name="origin"></param>
- /// <returns></returns>
- public static Connector GetConnectorByOrigin(List<Connector> connectors, XYZ origin)
- {
- return connectors.FirstOrDefault(c => c.ConnectorType == ConnectorType.End && c.Origin.IsEqual(origin));
- }
- /// <summary>
- /// 根据方向获取Connector
- /// </summary>
- /// <param name="connectors"></param>
- /// <param name="direction"></param>
- /// <returns></returns>
- public static Connector GetConnectorByDirection(List<Connector> connectors, XYZ direction)
- {
- return connectors.FirstOrDefault(c => c.ConnectorType == ConnectorType.End && c.CoordinateSystem.BasisZ.IsSameDirection(direction));
- }
- /// <summary>
- /// 获取与给定方向,夹角最小的点
- /// </summary>
- /// <param name="connectors"></param>
- /// <param name="direction"></param>
- /// <returns></returns>
- public static Connector GetConnectorByMinAngle(List<Connector> connectors, XYZ direction)
- {
- return GetConnectorByMinAngle(connectors, direction, double.MinValue);
- }
- /// <summary>
- /// 获取与给定方向,夹角最小的点
- /// </summary>
- /// <param name="connectors"></param>
- /// <param name="direction"></param>
- /// <param name="minAngleCosValue">夹角下限的Cos值,如果direction不是单位向量,该值未direction.length*夹角下限cos值</param>
- /// <returns></returns>
- public static Connector GetConnectorByMinAngle(List<Connector> connectors, XYZ direction, double minAngleCosValue)
- {
- Connector useConnector = null;
- double angle = minAngleCosValue;// double.MinValue;
- foreach (Connector connector in connectors)
- {
- var tempDirection = connector.CoordinateSystem.BasisZ;
- var tempAngle = direction.DotProduct(tempDirection);
- //点乘值越大,角度越小
- if (tempAngle.More(angle))
- {
- useConnector = connector;
- angle = tempAngle;
- }
- }
- return useConnector;
- }
- /// <summary>
- /// 获取给点附近的Connector
- /// </summary>
- /// <param name="connectors"></param>
- /// <param name="position"></param>
- /// <returns></returns>
- public static Connector GetNearConnector(List<Connector> connectors, XYZ position)
- {
- Connector resultConnector = null;
- double minDistance = double.MaxValue;
- foreach (var connector in connectors)
- {
- if (connector.ConnectorType != ConnectorType.End)
- {
- //只计算端点
- continue;
- }
- var tempLength = connector.Origin.DistanceTo(position);
- if (tempLength < minDistance)
- {
- resultConnector = connector;
- minDistance = tempLength;
- }
- }
- return resultConnector;
- }
- /// <summary>
- /// 计算两个风管的矩形对齐方式
- /// </summary>
- /// <param name="baseConnector"></param>
- /// <param name="otherConnector"></param>
- /// <returns></returns>
- public static RectangleAlignment CalcAlignment(Connector baseConnector, Connector otherConnector)
- {
- #region 确定Connector基准数据
- var firstConnector = baseConnector;
- var secondConnector = otherConnector;
- //如果两个Connector中出现圆形和非圆形的组合,则让非圆形Connector充当基准点
- if (firstConnector.Shape == ConnectorProfileType.Round && secondConnector.Shape != ConnectorProfileType.Round)
- {
- firstConnector = otherConnector;
- secondConnector = baseConnector;
- }
- #endregion
- #region 判断规则
- /*
- 1、Y平行,判断上下对齐方式
- 2、X平行,判断左右对齐方式
- 不平行的情况下,取居中设定
- Connector中上为-Y,左为-X
- 如果是圆形管道的话,要自定义上下,左右的方向;
- 圆形判定:中心点位置相同(连线与延伸方向平行),则为中心对齐。
- 两个中心在投影到平面内,做一个方向为左右对齐方向;
- 特殊如果,中心延长线与世界坐标Z轴垂直,则取Z轴为上下对齐方式
- */
- #endregion
- if (firstConnector.Shape == ConnectorProfileType.Round && secondConnector.Shape == ConnectorProfileType.Round)
- {
- //都是圆形特殊处理,圆形形式上而言只有中心对齐和边对齐
- #region 圆形连接件判定
- if (firstConnector.CoordinateSystem.BasisZ.IsParallel(secondConnector.CoordinateSystem.BasisZ))
- {
- var secondProject = secondConnector.Origin.GetPlaneProject(firstConnector.CoordinateSystem.BasisZ, firstConnector.Origin);
- var linkVector = secondProject - firstConnector.Origin;
- //简化处理
- #region 圆形构件对齐处理,中心对齐,或者左中对齐
- if (linkVector.IsParallel(secondConnector.CoordinateSystem.BasisZ))
- {
- return RectangleAlignment.CenterMiddle;
- }
- else
- {
- if (firstConnector.Radius.IsEqual(secondConnector.Radius + linkVector.GetLength()))
- {
- return RectangleAlignment.LeftMiddle;
- }
- }
- return RectangleAlignment.CenterMiddle;
- #endregion
- }
- else
- {
- //返回边对齐形式,边对齐是左右对齐。
- var baseDirection = firstConnector.CoordinateSystem.BasisZ.CrossProduct(secondConnector.CoordinateSystem.BasisZ);
- var secondProject = secondConnector.Origin.GetLineProject(baseDirection, firstConnector.Origin);
- var linkVector = secondProject - firstConnector.Origin;
- if (linkVector.GetLength().IsEqual(0))
- {
- return RectangleAlignment.CenterMiddle;
- }
- else if (firstConnector.Radius.IsEqual(secondConnector.Radius + linkVector.GetLength()))
- {
- return RectangleAlignment.LeftMiddle;
- }
- return RectangleAlignment.CenterMiddle;
- }
- #endregion
- }
- else
- {
- bool useUpDown = false, useLeftRight = false;
- XYZ upDownDirection = null, leftRightDirection = null;
- #region 方形连接件判定
- if (firstConnector.CoordinateSystem.BasisY.IsParallel(secondConnector.CoordinateSystem.BasisY))
- {
- useUpDown = true;
- upDownDirection = firstConnector.CoordinateSystem.BasisY.Negate();
- }
- if (firstConnector.CoordinateSystem.BasisX.IsParallel(secondConnector.CoordinateSystem.BasisX))
- {
- useLeftRight = true;
- leftRightDirection = firstConnector.CoordinateSystem.BasisX.Negate();
- }
- if (!useUpDown && !useLeftRight)
- {
- //默认返回正中对齐样式
- return RectangleAlignment.CenterMiddle;
- }
- #region 判断上下对齐
- VerticalAlign verticalAlignment = VerticalAlign.Middle;
- if (useUpDown)
- {
- var baseDirection = upDownDirection.Normalize();
- var secondProject = secondConnector.Origin.GetLineProject(baseDirection, firstConnector.Origin);
- var linkVector = secondProject - firstConnector.Origin;
- do
- {
- var secondDotValue = linkVector.DotProduct(baseDirection);
- if (secondDotValue.IsEqual(0))
- {
- verticalAlignment = VerticalAlign.Middle;
- break;
- }
- var firstLength = firstConnector.Height / 2;
- var secondLength = secondConnector.Shape == ConnectorProfileType.Round ? secondConnector.Radius : (secondConnector.Height / 2);
- if (firstLength.IsEqual(secondLength + secondDotValue))
- {
- verticalAlignment = VerticalAlign.Top;
- break;
- }
- if ((-firstLength).IsEqual(-secondLength + secondDotValue))
- {
- verticalAlignment = VerticalAlign.Bottom;
- break;
- }
- } while (false);
- }
- #endregion
- #region 判断左对齐
- HorizontalAlign horizontalAlignment = HorizontalAlign.Center;
- if (useLeftRight)
- {
- var baseDirection = leftRightDirection.Normalize();
- var secondProject = secondConnector.Origin.GetLineProject(baseDirection, firstConnector.Origin);
- var linkVector = secondProject - firstConnector.Origin;
- do
- {
- var secondDotValue = linkVector.DotProduct(baseDirection);
- if (secondDotValue.IsEqual(0))
- {
- horizontalAlignment = HorizontalAlign.Center;
- break;
- }
- var firstLength = firstConnector.Width / 2;
- var secondLength = secondConnector.Shape == ConnectorProfileType.Round ? secondConnector.Radius : (secondConnector.Width / 2);
- if (firstLength.IsEqual(secondLength + secondDotValue))
- {
- horizontalAlignment = HorizontalAlign.Left;
- break;
- }
- if ((-firstLength).IsEqual(-secondLength + secondDotValue))
- {
- horizontalAlignment = HorizontalAlign.Right;
- break;
- }
- } while (false);
- }
- #endregion
- #endregion
- return (RectangleAlignment)((int)horizontalAlignment | (int)verticalAlignment);
- }
- return RectangleAlignment.CenterMiddle;
- }
- }
- }
|