I am brand new to both blender and python, so i apologize in advance if i'm missing something simple, but i'm having trouble with my script. The purpose of my script is to hopefully delete the default cube in the scene, scan a folder for an obj file, import that obj and then make a duplicate of the imported obj and apply a decimate modifier to it.

import os
import bpy

decimate = 0.02
resolution = '4k'


full_path_to_directory = os.path.join('C:\\', 'Users', 'brand', 'Desktop', 'New folder (2)')
file_list = os.listdir(full_path_to_directory)
obj_list = [item for item in file_list if item[-3:] == 'obj']

for item in obj_list:
    full_path_to_file = os.path.join(full_path_to_directory, item)

for ob in bpy.context.selected_editable_objects:
    ob.active_material_index = 0
    for i in range(len(ob.material_slots)):
        bpy.ops.object.material_slot_remove({'object': ob})
        bpy.context.object.modifiers["Decimate"].ratio = decimate
        bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Decimate")

bpy.context.scene.render.engine = 'CYCLES'
bpy.context.scene.selected_col = True
bpy.context.scene.selected_rough = True
bpy.context.scene.selected_normal = True
bpy.context.scene.texture_res = resolution
bpy.context.scene.restoreOrigUVmap = False
bpy.context.scene.newUVoption = True

When i run the script, i get this error

Traceback (most recent call last):
  File "\Text", line 24, in <module>
  File "C:\Program Files\Blender Foundation\Blender 2.81\2.81\scripts\modules\bpy\ops.py", line 201, in __call__
    ret = op_call(self.idname_py(), None, kw)
RuntimeError: Operator bpy.ops.object.modifier_add.poll() failed, context is incorrect

However, if i delete the section that handles importing the obj from a folder and i simply apply the script to the default cube, everything works correctly and i get a duplicate with a decimate filter applied correctly. I have tried a few different ways of trying to fix this issue but i just cant seem to wrap my head around it, any help would be greatly appreciated. Thanks.


1 Answer 1


Add modifier using API, override the modifier apply.

Would use

m =  ob.modifiers.new(name="Foo", type='DECIMATE')
m.ratio = decimate

to add a modifier, and override the context of modifier apply operator, just as you have done for material link remove.

bpy.ops.object.modifier_apply({"object" : ob}, apply_as='DATA', modifier=m.name)

Questionable whether you want to add and apply modifier for each material slot, check your indenting

Alternatively can deselect all, set as active and select the active object in loop. To set the context to each individual object. Suggest is the Equivalent of you "simply applying script to default cube"

Eg for 2.8

context.view_layer.objects.active = ob

to give the loop object context.

However would recommend using as few operators as possible... see Python performance with Blender operators

Note incorrect context is a common cause of problems


  • $\begingroup$ I'm sorry to do this, but could i bother you with another question regarding this? In my script i'd like to get it to bake the materials from the high poly mesh down to the decimated low poly which requires me to have the original high poly mesh active and the low poly duplicate as the active object, but i can't seem to make that work. Sorry for continuing this, and thank you so much for your previous answer, it worked perfectly and actually helped me better understand how things work. Thanks again. $\endgroup$
    – Sapps
    Mar 25, 2020 at 0:03
  • $\begingroup$ Can select as many objects as you like by setting select. Equiv of context.selected_objects Can only have one active object. $\endgroup$
    – batFINGER
    Mar 25, 2020 at 13:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .