Getting Materials used by Instances in the project?

Getting Materials used by Instances in the project?

Anonymous
Not applicable
2,265 Views
3 Replies
Message 1 of 4

Getting Materials used by Instances in the project?

Anonymous
Not applicable

Hi,

 

I am trying to create a list of MaterialIds of materials that are not used within the document. I am doing this by getting all the instances within the document and using Instance.GetMaterialIds(bool) on each instance found within "nTypes" in the code bellow.

 

The string "materialIdsGotten" is used to collect all the ids of materials used by instances but for some reason even though i am using a fairly large project it is only collecting two materials. I'm guessing i missussing Instance.GetMaterialIds(bool) wrong. Can you please help me?

 

 

            FilteredElementCollector nTypes = new FilteredElementCollector(doc).WhereElementIsNotElementType();
            FilteredElementCollector Materials = new FilteredElementCollector(doc).OfClass(typeof(Material));
            List<ElementId> MaterialIds = Materials.ToElementIds().ToList<ElementId>();

            string materialIdsGotten = "";

            foreach (Element e in nTypes)
            {
                if (e is Instance)
                {
                    Instance i = (Instance)e;
                    if (e.Category != null)
                    {
                        if (e.Category.HasMaterialQuantities == true)
                        {
                            ICollection<ElementId> iMaterialIds = i.GetMaterialIds(true);
                            foreach (ElementId eId in iMaterialIds)
                            {
                                materialIdsGotten += doc.GetElement(eId).Name + "\n";
                                if (MaterialIds.Contains(eId))
                                {
                                    MaterialIds.Remove(eId);       //remove from list of Ids to be deleted.
                                }
                            }
                        }
                        else
                        {
                            ICollection<ElementId> iMaterialIds = i.GetMaterialIds(false);
                            foreach (ElementId eId in iMaterialIds)
                            {
                                materialIdsGotten += doc.GetElement(eId).Name +"\n";
                                if (MaterialIds.Contains(eId))
                                {
                                    MaterialIds.Remove(eId);      //remove from list of ids to be deleted
                                }
                            }
                        }
                    }
                }
            }

 

Thank you in advance

 

0 Likes
2,266 Views
3 Replies
Replies (3)
Message 2 of 4

Revitalizer
Advisor
Advisor

Hi,

 

in the RevitAPI.chm it says about the boolean parameter in the Element.GetMaterialIds method :

 

"returnPaintMaterials Type: System.Boolean
If true, this returns material ids assigned to element faces by the Paint tools. If false, this returns ids associated to the material through its geometry or compound structure layers."

 

That means:

If your user didn't use the paint tool to override element's faces by another material, you will get an empty collection.

So in fact, you need to call the method twice, once with parameter set to "true", once set to "false".

 

 

Regards,

Revitalizer




Rudolf Honke
Software Developer
Mensch und Maschine





Message 3 of 4

Anonymous
Not applicable

It has definetly helped get more materials used, not all of them but I will keep working on it and maybe come back to this thread if I am truly stuck.

 

Thanks a million.

0 Likes
Message 4 of 4

Anonymous
Not applicable

Hey Mendo, 

 

I've just done this exact thing in one of my macro's, and i saw this post. 

So here's how i do it: 

 

i have a collection.OfClass( FamilyInstance ) 

i have a matList[]

i have a matNameList[]

 

then i loop through the project

for f in collection:

    paraMaterial = f.Symbol.get_Parameter( BuiltInParameter.STRUCTURAL_MATERIAL_PARAM ) 

    material = doc.GetElement( paraMaterial.AsElementId() ) 

    if material != None:

        if material.Name not in matNameList: 

            matNameList.Add( material.Name ) 

            matList.Add( material ) 

 

after going through this loop your matList[] contains all the materials used in the project (only one instance of every material)

 

if you want to assign a material you can use this format: 

 

paraMaterial.Set( material.Id ) # paraMaterial contains your familyInstance reference, and material can be an item in your list. 

 

Hope this helps you 😉 

 

0 Likes