Dear Wils,
Thank you for your appreciation and nice sample utility macro.
I looked at the code and just happened to notice that your unused utility methods getSheets and getViewPorts are extremely ineffective, cf.:
http://thebuildingcoder.typepad.com/blog/2012/09/findelement-and-collector-optimisation.html
They are not used here, and they should be removed (and not used anywhere else either).
Thank you to @MarryTookMyCoffe for his question... I wonder too.
In case he is right, I prefer writing `0 < s.Elements.Size` instead of `1 <=`.
What do you think about his suggestion? He is probably more experienced...
Looking further at your code:
If `elemConnector.MEPSystem` can ever be null, then you must check for that before calling its `Name` property, not afterwards.
As soon as you call the property on a null object, .NET will throw an exception.
There is no need to call `GetOrderedParameters` and iterate over all parameters to find the "Mark" one.
You can retrieve it directly using the built-in parameter `ALL_MODEL_MARK`:
// No need to iterate over all parameters:
IList<Parameter> eParams = e.GetOrderedParameters();
foreach( Parameter p in eParams )
{
if( p.Definition.Name.Equals( "Mark" ) )
{
sb.Append( "Family Instance: " + p.AsString() );
sb.Append( " has a connector {" + cnctrSys + "} which is connected to a {" + cnntdSys + "} system..." + "\n\n" );
}
}
// Also, you should not use the display name if you can avoid it:
Parameter p2 = e.LookupParameter( "Mark" );
// Always use the built-in parameter enum if you can:
Parameter p3 = e.get_Parameter(
BuiltInParameter.ALL_MODEL_MARK );
sb.Append( "Family Instance: " + p3.AsString() );
sb.Append( " has a connector {" + cnctrSys
+ "} which is connected to a {" + cnntdSys
+ "} system..." + "\n\n" );
I ended up cleaning it up by implementing a helper method:
/// <summary>
/// Add a system mismatch entry to the string builder
/// </summary>
static void ReportSystemMistmatch(
StringBuilder sb,
Element e,
string cnctrSys,
string cnntdSys )
{
Parameter p = e.get_Parameter(
BuiltInParameter.ALL_MODEL_MARK );
sb.Append( string.Format( "Family instance '{0}' "
+ "has a connector {{{1}}} that is connected to a "
+ "{{{2}}} system...\n\n",
p.AsString(), cnctrSys, cnntdSys ) );
}
Then the code can be reduced to this:
/// <summary>
/// Report MEP system mismatches
/// </summary>
static void FindMismatch( Document doc )
{
string cnntdSys = "";
string cnctrSys = "";
StringBuilder sb = new StringBuilder();
FilteredElementCollector systems
= new FilteredElementCollector( doc )
.OfClass( typeof( MEPSystem ) );
IEnumerable<MEPSystem> desirableSystems = systems
.Cast<MEPSystem>()
.Where<MEPSystem>( s
=> IsDesirableSystemPredicate( s ) );
foreach( MEPSystem system in desirableSystems )
{
if( system.GetType() == typeof( PipingSystem ) )
{
cnntdSys = ( system as PipingSystem ).SystemType.ToString();
}
if( system.GetType() == typeof( MechanicalSystem ) )
{
cnntdSys = ( system as MechanicalSystem ).SystemType.ToString();
}
ElementSet mepSet = system.Elements;
foreach( Element e in mepSet )
{
ConnectorSet mepCS = MepSystemSearch.GetConnectors( e );
foreach( Connector elemConnector in mepCS )
{
if( elemConnector.Domain.Equals(
Domain.DomainPiping ) )
{
cnctrSys = elemConnector.PipeSystemType.ToString();
if( elemConnector.MEPSystem != null
&& elemConnector.MEPSystem.Name.Equals(
system.Name ) )
{
if( elemConnector.PipeSystemType.Equals(
( system as PipingSystem ).SystemType ) )
{
// Do Nothing
}
else
{
ReportSystemMistmatch( sb, e,
cnctrSys, cnntdSys );
}
}
}
if( null != elemConnector.MEPSystem
&& elemConnector.Domain.Equals(
Domain.DomainHvac ) )
{
cnctrSys = elemConnector.DuctSystemType.ToString();
if( elemConnector.MEPSystem.Name.Equals(
system.Name ) )
{
if( elemConnector.DuctSystemType.Equals(
( system as MechanicalSystem ).SystemType ) )
{
// Do Nothing
}
else
{
ReportSystemMistmatch( sb, e,
cnctrSys, cnntdSys );
}
}
}
}
}
}
TaskDialog.Show( "Flow Mismatch", sb + "\n" );
}
I added the edited code to The Building Coder samples for preservation for posterity:
https://github.com/jeremytammik/the_building_coder_samples
In the new module CmdFlowMismatch.cs:
https://github.com/jeremytammik/the_building_coder_samples/blob/master/BuildingCoder/BuildingCoder/C...
I hope this helps.
Can you provide a small sample model to test run it in?
Thank you!
Cheers,
Jeremy