123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- using Autodesk.Revit.DB;
- using Autodesk.Revit.DB.Electrical;
- using FWindSoft.SystemExtensions;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- namespace FWindSoft.Revit.Mep
- {
- /*
- * 连接相关的相代码
- */
- /// <summary>
- /// 连接管道基础类
- /// </summary>
- public abstract class BaseJoinConduit : IJoinCurve
- {
- /// <summary>
- /// 连接管线
- /// </summary>
- /// <param name="elements"></param>
- /// <param name="context"></param>
- /// <returns></returns>
- protected abstract bool JoinImpl(List<JoinElementWraper> elements, JoinContext context);
- /// <summary>
- /// 连接管线
- /// </summary>
- /// <param name="elements"></param>
- /// <param name="context"></param>
- public bool Join(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements.Any(ew => !(ew.AssociateElement is Conduit)))
- {
- return false;
- }
- return JoinImpl(elements, context);
- }
- }
- #region 两个管道进行连接
- public class Join2Conduit : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 2)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- BaseJoinConduit joinConduit;
- if (line1.IsCollinear(line2))
- {
- if (conduit1.Diameter.IsEqual(conduit2.Diameter))
- {
- joinConduit = new Join2ConduitByUnion();
- }
- else
- {
- joinConduit = new Join2ConduitByTransition();
- }
- }
- else
- {
- joinConduit = new Join2ConduitByElbow();
- }
- if (joinConduit != null)
- {
- return joinConduit.Join(elements, context);
- }
- return false;
- }
- }
- /// <summary>
- /// 使用活接头连接
- /// </summary>
- public class Join2ConduitByUnion : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 2)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- if (!conduit1.Diameter.IsEqual(conduit2.Diameter) || !line1.IsCollinear(line2))
- {
- return false;
- }
- //找到connector方向相反,且距离较近的一对点,创建连接
- var connectors = conduit1.GetAllConnectors();
- Connector useConnector1 = null, useConnector2 = null;
- double distance = double.MaxValue;
- foreach (Connector connector in connectors)
- {
- var refConnector = conduit2.GetConnectorByDirection(-connector.CoordinateSystem.BasisZ);
- if (refConnector != null)
- {
- var tempLength = connector.Origin.DistanceTo(refConnector.Origin);
- if (tempLength.Less(distance))
- {
- useConnector1 = connector;
- useConnector2 = refConnector;
- distance = tempLength;
- }
- }
- }
- FamilyInstance fi = null;
- if (useConnector1 != null && useConnector1 != null)
- {
- var line2Other = line2.GetFarnessPoint(useConnector2.Origin);
- if (line2Other.Subtract(useConnector1.Origin).GetLength().More(JoinConduitUtils.FaultTolerantLength))
- {
- fi = ConduitFittingCreator.NewUnionFitting(useConnector1, useConnector2, context);
- }
- }
- return fi != null;
- }
- }
- /// <summary>
- /// 使用变径连接
- /// </summary>
- public class Join2ConduitByTransition : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 2)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- if (conduit1.Diameter.IsEqual(conduit2.Diameter) || !line1.IsCollinear(line2))
- {
- return false;
- }
- //找到connector方向相反,且距离较近的一对点,创建连接
- var connectors = conduit1.GetAllConnectors();
- Connector useConnector1 = null, useConnector2 = null;
- double distance = double.MaxValue;
- foreach (Connector connector in connectors)
- {
- var refConnector = conduit2.GetConnectorByDirection(-connector.CoordinateSystem.BasisZ);
- if (refConnector != null)
- {
- var tempLength = connector.Origin.DistanceTo(refConnector.Origin);
- if (tempLength.Less(distance))
- {
- useConnector1 = connector;
- useConnector2 = refConnector;
- distance = tempLength;
- }
- }
- }
- FamilyInstance fi = null;
- if (useConnector1 != null && useConnector1 != null)
- {
- var line2Other = line2.GetFarnessPoint(useConnector2.Origin);
- if (line2Other.Subtract(useConnector1.Origin).GetLength().More(JoinConduitUtils.FaultTolerantLength))
- {
- fi = ConduitFittingCreator.NewTransitionFitting(useConnector1, useConnector2, context);
- }
- }
- return fi != null;
- }
- }
- /// <summary>
- /// 使用弯头连接
- /// </summary>
- public class Join2ConduitByElbow : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 2)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- var lineUnbound1 = line1.CloneUnbound();
- var lineUnbound2 = line2.CloneUnbound();
- var intersectPoint = lineUnbound1.GetSpatialIntersection(lineUnbound2);
- if (null == intersectPoint)
- {
- return false;
- }
- Connector connector1 = conduit1.GetConnectorByOrigin(line1.GetNearnessPoint(intersectPoint));
- Connector connector2 = conduit2.GetConnectorByOrigin(line2.GetNearnessPoint(intersectPoint));
- FamilyInstance fi = ConduitFittingCreator.NewElbowFitting(connector1, connector2, context);
- return fi != null;
- }
- }
- #endregion
- #region 三个管道进行连接
- /// <summary>
- /// 连接三个管道
- /// </summary>
- public class Join3Conduit : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 3)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var conduit3 = elements[2].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- var line3 = conduit3.GetLocationLine();
- #region 算法流程
- /*
- * 取到conduit使用的三通。
- * 在交点位置放置三通,顶面Connector朝下。
- * 旋转到相应的位置,将匹配的Connector进行连接
- * 匹配Connector未能按默认连接,进行特殊处理?
- *
- * 尽量保证线盒横放。如果位置关系不允许横放,再考虑其他摆放
- * 分类:两两垂直;一个与其中一个平行,与另一个垂直
- */
- #endregion
- //正常情况下,一条线,必然和其余两条线存在不平行的情况
- XYZ ins = null;
- if (!line1.IsParallel(line2))
- {
- ins = line1.GetSpatialIntersection(line2);
- }
- else if (!line1.IsParallel(line3))
- {
- ins = line1.GetSpatialIntersection(line3);
- }
- if (ins != null)
- {
- var fi = ConduitFittingCreator.NewTeeFitting(conduit1.GetNearnessConnector(ins), conduit2.GetNearnessConnector(ins), conduit3.GetNearnessConnector(ins), context);
- return fi != null;
- }
- return false;
- }
- }
- #endregion
- #region 四个管道进行连接
- /// <summary>
- /// 连接四个管道
- /// </summary>
- public class Join4Conduit : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 3)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var conduit3 = elements[2].AssociateElement as Conduit;
- var conduit4 = elements[3].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- var line3 = conduit3.GetLocationLine();
- var line4 = conduit4.GetLocationLine();
- //正常情况下,一条线,必然和其余两条线存在不平行的情况
- XYZ ins = null;
- if (!line1.IsParallel(line2))
- {
- ins = line1.GetSpatialIntersection(line2);
- }
- else if (!line1.IsParallel(line3))
- {
- ins = line1.GetSpatialIntersection(line3);
- }
- if (ins != null)
- {
- var fi = ConduitFittingCreator.NewCrossFitting(conduit1.GetNearnessConnector(ins), conduit2.GetNearnessConnector(ins), conduit3.GetNearnessConnector(ins), conduit4.GetNearnessConnector(ins), context);
- return fi != null;
- }
- return false;
- }
- }
- #endregion
- #region 五个个管道进行连接
- /// <summary>
- /// 连接五个管道
- /// </summary>
- public class Join5Conduit : BaseJoinConduit
- {
- protected override bool JoinImpl(List<JoinElementWraper> elements, JoinContext context)
- {
- if (elements == null || elements.Count < 3)
- {
- return false;
- }
- var conduit1 = elements[0].AssociateElement as Conduit;
- var conduit2 = elements[1].AssociateElement as Conduit;
- var conduit3 = elements[2].AssociateElement as Conduit;
- var conduit4 = elements[3].AssociateElement as Conduit;
- var conduit5 = elements[4].AssociateElement as Conduit;
- var line1 = conduit1.GetLocationLine();
- var line2 = conduit2.GetLocationLine();
- var line3 = conduit3.GetLocationLine();
- var line4 = conduit4.GetLocationLine();
- var line5 = conduit5.GetLocationLine();
- //正常情况下,一条线,必然和其余两条线存在不平行的情况
- XYZ ins = null;
- if (!line1.IsParallel(line2))
- {
- ins = line1.GetSpatialIntersection(line2);
- }
- else if (!line1.IsParallel(line3))
- {
- ins = line1.GetSpatialIntersection(line3);
- }
- if (ins != null)
- {
- var fi = ConduitFittingCreator.NewFiveLinksFitting(conduit1.GetNearnessConnector(ins), conduit2.GetNearnessConnector(ins), conduit3.GetNearnessConnector(ins), conduit4.GetNearnessConnector(ins), conduit5.GetNearnessConnector(ins), context);
- return fi != null;
- }
- return false;
- }
- }
- #endregion
- }
|