diff --git a/BuildingCoder/BuildingCoder/CmdMepElementShape.cs b/BuildingCoder/BuildingCoder/CmdMepElementShape.cs index 2d29c907..e62e170b 100644 --- a/BuildingCoder/BuildingCoder/CmdMepElementShape.cs +++ b/BuildingCoder/BuildingCoder/CmdMepElementShape.cs @@ -474,13 +474,14 @@ static public MEPSystem ExtractMechanicalOrPipingSystem( return system; } - // copied from sdk - TraverseSystem example + // + // Copied from Revit SDK TraverseSystem example // // (C) Copyright 2003-2010 by Autodesk, Inc. // /// /// Get the mechanical or piping system - /// from the connectors of selected element + /// from the connectors of selected element. /// /// Connectors of selected element /// The found mechanical or piping system diff --git a/BuildingCoder/BuildingCoder/CmdRollingOffset.cs b/BuildingCoder/BuildingCoder/CmdRollingOffset.cs index 74e509b5..d1cecc54 100644 --- a/BuildingCoder/BuildingCoder/CmdRollingOffset.cs +++ b/BuildingCoder/BuildingCoder/CmdRollingOffset.cs @@ -273,6 +273,8 @@ double remainingPipeLength using( Transaction tx = new Transaction( doc ) ) { + Pipe pipe = null; + tx.Start( "Rolling Offset" ); if( _place_model_line ) @@ -295,7 +297,7 @@ double remainingPipeLength } else { - Pipe pipe = pipes[0]; + pipe = pipes[0]; if( _use_static_pipe_create ) { @@ -348,6 +350,15 @@ PipeType pipe_type_standard } } + if( null != pipe ) + { + // Connect rolling offset pipe segment + // with its neighbours + + Util.Connect( q0, pipes[0], pipe ); + Util.Connect( q1, pipe, pipes[1] ); + } + tx.Commit(); } return Result.Succeeded; diff --git a/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs b/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs index 02a95bb4..22500b4f 100644 --- a/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs +++ b/BuildingCoder/BuildingCoder/Properties/AssemblyInfo.cs @@ -31,5 +31,5 @@ // // You can specify all the values or you can default the Revision and Build Numbers // by using the '*' as shown below: -[assembly: AssemblyVersion( "2014.0.106.2" )] -[assembly: AssemblyFileVersion( "2014.0.106.2" )] +[assembly: AssemblyVersion( "2014.0.106.3" )] +[assembly: AssemblyFileVersion( "2014.0.106.3" )] diff --git a/BuildingCoder/BuildingCoder/Util.cs b/BuildingCoder/BuildingCoder/Util.cs index 5021489a..0609fa64 100644 --- a/BuildingCoder/BuildingCoder/Util.cs +++ b/BuildingCoder/BuildingCoder/Util.cs @@ -913,6 +913,148 @@ FilteredElementCollector collector return null; } #endregion // Element filtering + + #region MEP utilities + /// + /// Return the given element's connector manager, + /// using either the family instance MEPModel or + /// directly from the MEPCurve connector manager + /// for ducts and pipes. + /// + static ConnectorManager GetConnectorManager( + Element e ) + { + MEPCurve mc = e as MEPCurve; + FamilyInstance fi = e as FamilyInstance; + + if( null == mc && null == fi ) + { + throw new ArgumentException( + "Element is neither an MEP curve nor a fitting." ); + } + + return null == mc + ? fi.MEPModel.ConnectorManager + : mc.ConnectorManager; + } + + /// + /// Return the element's connector at the given + /// location, and its other connector as well, + /// in case there are exactly two of them. + /// + /// An element, e.g. duct, pipe or family instance + /// The location of one of its connectors + /// The other connector, in case there are just two of them + /// The connector at the given location + static Connector GetConnectorAt( + Element e, + XYZ location, + out Connector otherConnector ) + { + otherConnector = null; + + Connector targetConnector = null; + + ConnectorManager cm = GetConnectorManager( e ); + + bool hasTwoConnectors = 2 == cm.Connectors.Size; + + foreach( Connector c in cm.Connectors ) + { + if( c.Origin.IsAlmostEqualTo( location ) ) + { + targetConnector = c; + + if( !hasTwoConnectors ) + { + break; + } + } + else if( hasTwoConnectors ) + { + otherConnector = c; + } + } + return targetConnector; + } + + /// + /// Return the connector in the set + /// closest to the given point. + /// + static Connector GetConnectorClosestTo( + ConnectorSet connectors, + XYZ p ) + { + Connector targetConnector = null; + double minDist = double.MaxValue; + + foreach( Connector c in connectors ) + { + double d = c.Origin.DistanceTo( p ); + + if( d < minDist ) + { + targetConnector = c; + minDist = d; + } + } + return targetConnector; + } + + /// + /// Return the connector on the element + /// closest to the given point. + /// + static Connector GetConnectorClosestTo( + Element e, + XYZ p ) + { + ConnectorManager cm = GetConnectorManager( e ); + + return null == cm + ? null + : GetConnectorClosestTo( cm.Connectors, p ); + } + + /// + /// Connect two MEP elements at a given point p. + /// + /// Thrown if + /// one of the given elements lacks connectors. + /// + public static void Connect( + XYZ p, + Element a, + Element b ) + { + ConnectorManager cm = GetConnectorManager( a ); + + if( null == cm ) + { + throw new ArgumentException( + "Element a has no connectors." ); + } + + Connector ca = GetConnectorClosestTo( + cm.Connectors, p ); + + cm = GetConnectorManager( b ); + + if( null == cm ) + { + throw new ArgumentException( + "Element b has no connectors." ); + } + + Connector cb = GetConnectorClosestTo( + cm.Connectors, p ); + + ca.ConnectTo( cb ); + //cb.ConnectTo( ca ); + } + #endregion // MEP utilities } #region Extension Method Classes