Changing a material.Category in bulk.

edited December 2023 in General

Let's say you have (100) IfcMaterials with the Category = Foo. If you want to change the Category of all these instances to Bar, can you do this in bulk with BB?

steverugiAce

Comments

  • You can run this script:

    import blenderbim.tool as tool
    import blenderbim.core.material as core
    
    
    for material in tool.Ifc.get().by_type("IfcMaterial"):
        if "Foo" in material.Category:
            tool.Ifc.run("material.edit_material", material=material, attributes={"Category": "Bar"})
    
    core.load_materials(tool.Material, "IfcMaterial")
    
    theoryshawsteverugi
  • edited December 2023

    @SigmaDimensions said:
    You can run this script:

    import blenderbim.tool as tool
    import blenderbim.core.material as core
    
    
    for material in tool.Ifc.get().by_type("IfcMaterial"):
        if "Foo" in material.Category:
            tool.Ifc.run("material.edit_material", material=material, attributes={"Category": "Bar"})
    
    core.load_materials(tool.Material, "IfcMaterial")
    

    my python knowledge is very basic and ChatGPT wasn't helpful

    on my machine it returns an error

    Python: Traceback (most recent call last):  
      File "\Text", line 6, in <module>  
    TypeError: argument of type 'NoneType' is not iterable
    

    do I have to add something to the script? in the test model I set the material Foo to 2 elements, thanks

  • edited December 2023

    try this...

    import blenderbim.tool as tool
    import blenderbim.core.material as core
    
    materials = tool.Ifc.get().by_type("IfcMaterial")
    
    for material in materials:
        if material.Category == "Foo":
            tool.Ifc.run("material.edit_material", material=material, attributes={"Category": "Bar"})
    
    core.load_materials(tool.Material, "IfcMaterial")
    
  • edited December 2023

    @theoryshaw said:
    try this...

    import blenderbim.tool as tool
    import blenderbim.core.material as core
    
    materials = tool.Ifc.get().by_type("IfcMaterial")
    
    for material in materials:
        if material.Category == "Foo":
            tool.Ifc.run("material.edit_material", material=material, attributes={"Category": "Bar"})
    
    core.load_materials(tool.Material, "IfcMaterial")
    

    wow, that was quick :D
    it worked out just fine, thanks a bunch
    EDIT
    the first script was correct but I used 'Foo' for material name, not Category, my bad

  • @steverugi

    do I have to add something to the script? in the test model I set the material Foo to 2 elements, thanks

    Were you adding a Blender material to multiple objects? I think you don't have any IfcMaterial entities, so the loop isn't working.
    In your test, no need for the material to be assigned to an object - you just need one or more IfcMaterial, with category="Foo". The material name can be whatever you want.

    We can add a or [] to the for loop to avoid errors when there are no ifc materials in the current file, but then the script won't do anything, making it pointless :D Sometimes errors are good!

    for material in tool.Ifc.get().by_type("IfcMaterial") or []:
    
  • @SigmaDimensions said:
    @steverugi

    do I have to add something to the script? in the test model I set the material Foo to 2 elements, thanks

    Were you adding a Blender material to multiple objects? I think you don't have any IfcMaterial entities, so the loop isn't working.
    In your test, no need for the material to be assigned to an object - you just need one or more IfcMaterial, with category="Foo". The material name can be whatever you want.

    We can add a or [] to the for loop to avoid errors when there are no ifc materials in the current file, but then the script won't do anything, making it pointless :D Sometimes errors are good!

    for material in tool.Ifc.get().by_type("IfcMaterial") or []:
    

    Yes, sorry I mistakenly used 'Foo' for the Name not the Category, your script is working OK, sorry!

Sign In or Register to comment.