BuildingCoder.NestedFamilyFunctions.GetFilteredNestedFamilyInstances C# (CSharp) Метод

GetFilteredNestedFamilyInstances() публичный статический Метод

Returns a list of family instances found in the given family document whose family file name matches the given familyFileNameFilter and whose type name matches the given typeNameFilter. If no filter values are provided (or they evaluate to the empty string when trimmed) then all instances will be evaluated. Filtering is done with a simple Contains (substring) check, so wildcards don't work.
Because standard Revit filtering techniques fail when searching for nested families in a family document, we have no choice but to iterate over all elements in the family. While there usually aren't that many elements at the family level, nonetheless this method has been built for MAXIMUM SPEED.
public static GetFilteredNestedFamilyInstances ( string familyFileNameFilter, string typeNameFilter, Document familyDocument, bool caseSensitiveFiltering ) : List
familyFileNameFilter string The portion of the nested family file name (or exact match) to find
typeNameFilter string The portion of the type name (or exact match) to find
familyDocument Document The family document to search.
caseSensitiveFiltering bool Whether or not the filter checking is case-sensitive
Результат List
        public static List<FamilyInstance> GetFilteredNestedFamilyInstances(
            string familyFileNameFilter,
            string typeNameFilter,
            Document familyDocument,
            bool caseSensitiveFiltering)
        {
            // Following good SOA practices, verify the
              // incoming data can be worked with.

              ValidateFamilyDocument( familyDocument ); // Throws an exception if not a family doc

              // The filters can be null

              List<FamilyInstance> oResult
            = new List<FamilyInstance>();

              FamilyInstance oFamilyInstanceCandidate;
              FamilySymbol oFamilySymbolCandidate;

              List<Family> oMatchingNestedFamilies
            = new List<Family>();

              List<FamilyInstance> oAllFamilyInstances
            = new List<FamilyInstance>();

              bool bFamilyFileNameFilterExists = true;
              bool bTypeNameFilterExists = true;

              // Set up some fast-to-test boolean values, which will be
              // used for short-circuit Boolean evaluation later.

              if( string.IsNullOrEmpty( familyFileNameFilter ) )
              {
            bFamilyFileNameFilterExists = false;
              }

              if( string.IsNullOrEmpty( typeNameFilter ) )
              {
            bTypeNameFilterExists = false;
              }

              // Unfortunately detecting nested families in a family document requires iterating
              // over all the elements in the document, because the built-in filtering mechanism
              // doesn't work for this case.  However, families typically don't have nearly as many
              // elements as a whole project, so the performance hit shouldn't be too bad.

              // Still, the fastest performance should come by iterating over all elements in the given
              // family document exactly once, keeping subsets of the family instances found for
              // later testing against the nested family file matches found.

              ElementClassFilter fFamilyClass = new ElementClassFilter( typeof( Family ) );
              ElementClassFilter fFamInstClass = new ElementClassFilter( typeof( FamilyInstance ) );
              LogicalOrFilter f = new LogicalOrFilter( fFamilyClass, fFamInstClass );
              FilteredElementCollector collector = new FilteredElementCollector( familyDocument );
              collector.WherePasses( f );

              foreach( Element e in collector )
              {
            // See if this is a family file nested into the current family document.

            Family oNestedFamilyFileCandidate = e as Family;

            if( oNestedFamilyFileCandidate != null )
            {
              // Must ask the "Element" version for it's name, because the Family object's
              // name is always the empty string.
              if( !bFamilyFileNameFilterExists
            || FilterMatches( oNestedFamilyFileCandidate.Name,
              familyFileNameFilter, caseSensitiveFiltering ) )
              {
            // This is a nested family file, and either no valid family file name filter was
            // given, or the name of this family file matches the filter.

            oMatchingNestedFamilies.Add( oNestedFamilyFileCandidate );
              }
            }
            else
            {
              // This element is not a nested family file definition, see if it's a
              // nested family instance.

              oFamilyInstanceCandidate
            = e as FamilyInstance;

              if( oFamilyInstanceCandidate != null )
              {
            // Just add the family instance to our "all" collection for later testing
            // because we may not have yet found all the matching nested family file
            // definitions.
            oAllFamilyInstances.Add( oFamilyInstanceCandidate );
              }
            }

              } // End iterating over all the elements in the family document exactly once

              // See if any matching nested family file definitions were found.  Only do any
              // more work if at least one was found.
              foreach( Family oMatchingNestedFamilyFile
            in oMatchingNestedFamilies )
              {
            // Count backwards through the all family instances list.  As we find
            // matches on this iteration through the matching nested families, we can
            // delete them from the candidates list to reduce the number of family
            // instance candidates to test for later matching nested family files to be tested
            for( int iCounter = oAllFamilyInstances.Count - 1;
              iCounter >= 0; iCounter-- )
            {
              oFamilyInstanceCandidate
            = oAllFamilyInstances[iCounter];

            #if _2010
              oFamilySymbolCandidate
            = oFamilyInstanceCandidate.ObjectType
              as FamilySymbol;
            #endif // _2010

              ElementId id = oFamilyInstanceCandidate.GetTypeId();
              oFamilySymbolCandidate = familyDocument.GetElement( id )
            as FamilySymbol;

              if( oFamilySymbolCandidate.Family.UniqueId
            == oMatchingNestedFamilyFile.UniqueId )
              {
            // Only add this family instance to the results if there was no type name
            // filter, or this family instance's type matches the given filter.

            if( !bTypeNameFilterExists
              || FilterMatches( oFamilyInstanceCandidate.Name,
                typeNameFilter, caseSensitiveFiltering ) )
            {
              oResult.Add( oFamilyInstanceCandidate );
            }

            // No point in testing this one again,
            // since we know its family definition
            // has already been processed.

            oAllFamilyInstances.RemoveAt( iCounter );
              }

            } // Next family instance candidate

              } // End of for each matching nested family file definition found

              return oResult;
        }

Usage Example

        public Result Execute(
            ExternalCommandData commandData,
            ref string message,
            ElementSet elements)
        {
            UIApplication app = commandData.Application;
            Document      doc = app.ActiveUIDocument.Document;

            string familyFilenameFilter = string.Empty;
            string typeNameFilter       = string.Empty;
            bool   caseSensitive        = false;

            IEnumerable <Family> nestedFamilies
                = NestedFamilyFunctions.GetFilteredNestedFamilyDefinitions(
                      familyFilenameFilter, doc, caseSensitive);

            foreach (Family f in nestedFamilies)
            {
                Debug.WriteLine(f.Name);
            }

            List <FamilyInstance> instances
                = NestedFamilyFunctions.GetFilteredNestedFamilyInstances(
                      familyFilenameFilter, typeNameFilter, doc, caseSensitive);

            foreach (FamilyInstance fi in instances)
            {
                Debug.WriteLine(Util.ElementDescription(fi));
            }

            return(Result.Failed);
        }