Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Getting Materials used by Instances in the project?

3 REPLIES 3
Reply
Message 1 of 4
Anonymous
2121 Views, 3 Replies

Getting Materials used by Instances in the project?

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

 

3 REPLIES 3
Message 2 of 4
Revitalizer
in reply to: Anonymous

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
in reply to: Revitalizer

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.

Message 4 of 4
Anonymous
in reply to: Anonymous

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 😉 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report