@@ -913,6 +913,148 @@ FilteredElementCollector collector
913913 return null ;
914914 }
915915 #endregion // Element filtering
916+
917+ #region MEP utilities
918+ /// <summary>
919+ /// Return the given element's connector manager,
920+ /// using either the family instance MEPModel or
921+ /// directly from the MEPCurve connector manager
922+ /// for ducts and pipes.
923+ /// </summary>
924+ static ConnectorManager GetConnectorManager (
925+ Element e )
926+ {
927+ MEPCurve mc = e as MEPCurve ;
928+ FamilyInstance fi = e as FamilyInstance ;
929+
930+ if ( null == mc && null == fi )
931+ {
932+ throw new ArgumentException (
933+ "Element is neither an MEP curve nor a fitting." ) ;
934+ }
935+
936+ return null == mc
937+ ? fi . MEPModel . ConnectorManager
938+ : mc . ConnectorManager ;
939+ }
940+
941+ /// <summary>
942+ /// Return the element's connector at the given
943+ /// location, and its other connector as well,
944+ /// in case there are exactly two of them.
945+ /// </summary>
946+ /// <param name="e">An element, e.g. duct, pipe or family instance</param>
947+ /// <param name="location">The location of one of its connectors</param>
948+ /// <param name="otherConnector">The other connector, in case there are just two of them</param>
949+ /// <returns>The connector at the given location</returns>
950+ static Connector GetConnectorAt (
951+ Element e ,
952+ XYZ location ,
953+ out Connector otherConnector )
954+ {
955+ otherConnector = null ;
956+
957+ Connector targetConnector = null ;
958+
959+ ConnectorManager cm = GetConnectorManager ( e ) ;
960+
961+ bool hasTwoConnectors = 2 == cm . Connectors . Size ;
962+
963+ foreach ( Connector c in cm . Connectors )
964+ {
965+ if ( c . Origin . IsAlmostEqualTo ( location ) )
966+ {
967+ targetConnector = c ;
968+
969+ if ( ! hasTwoConnectors )
970+ {
971+ break ;
972+ }
973+ }
974+ else if ( hasTwoConnectors )
975+ {
976+ otherConnector = c ;
977+ }
978+ }
979+ return targetConnector ;
980+ }
981+
982+ /// <summary>
983+ /// Return the connector in the set
984+ /// closest to the given point.
985+ /// </summary>
986+ static Connector GetConnectorClosestTo (
987+ ConnectorSet connectors ,
988+ XYZ p )
989+ {
990+ Connector targetConnector = null ;
991+ double minDist = double . MaxValue ;
992+
993+ foreach ( Connector c in connectors )
994+ {
995+ double d = c . Origin . DistanceTo ( p ) ;
996+
997+ if ( d < minDist )
998+ {
999+ targetConnector = c ;
1000+ minDist = d ;
1001+ }
1002+ }
1003+ return targetConnector ;
1004+ }
1005+
1006+ /// <summary>
1007+ /// Return the connector on the element
1008+ /// closest to the given point.
1009+ /// </summary>
1010+ static Connector GetConnectorClosestTo (
1011+ Element e ,
1012+ XYZ p )
1013+ {
1014+ ConnectorManager cm = GetConnectorManager ( e ) ;
1015+
1016+ return null == cm
1017+ ? null
1018+ : GetConnectorClosestTo ( cm . Connectors , p ) ;
1019+ }
1020+
1021+ /// <summary>
1022+ /// Connect two MEP elements at a given point p.
1023+ /// </summary>
1024+ /// <exception cref="ArgumentException">Thrown if
1025+ /// one of the given elements lacks connectors.
1026+ /// </exception>
1027+ public static void Connect (
1028+ XYZ p ,
1029+ Element a ,
1030+ Element b )
1031+ {
1032+ ConnectorManager cm = GetConnectorManager ( a ) ;
1033+
1034+ if ( null == cm )
1035+ {
1036+ throw new ArgumentException (
1037+ "Element a has no connectors." ) ;
1038+ }
1039+
1040+ Connector ca = GetConnectorClosestTo (
1041+ cm . Connectors , p ) ;
1042+
1043+ cm = GetConnectorManager ( b ) ;
1044+
1045+ if ( null == cm )
1046+ {
1047+ throw new ArgumentException (
1048+ "Element b has no connectors." ) ;
1049+ }
1050+
1051+ Connector cb = GetConnectorClosestTo (
1052+ cm . Connectors , p ) ;
1053+
1054+ ca . ConnectTo ( cb ) ;
1055+ //cb.ConnectTo( ca );
1056+ }
1057+ #endregion // MEP utilities
9161058 }
9171059
9181060 #region Extension Method Classes
0 commit comments