Hello there. I’m working on some Python addons for Blender, but I’m having a lot of problem understanding the hidden states. I have working scripts but whenever I try to add UIs for them, simply to run the functions, they stop working. I’ve been struggling with that for a week and have asked a number of times on BlenderArtists and IRC (both #blender and #blenderpython) but nobody was able to help so far, so someone told me I should ask here and try to reach “Campbell Barton”. I’m not sure if that’s fine because I guess it’s probably something really stupid I’m doing it’s just not a well documented behavior, but here we go:
From here:
import bpy
class SimpleOperator(bpy.types.Operator):
"""Tooltip"""
bl_idname = "object.simple_operator"
bl_label = "Simple Object Operator"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
context = bpy.context
scene = context.scene
selected_objs = context.selected_objects[:] #copy just in case
print("\nstarting")
for obj in selected_objs:
bpy.ops.object.select_all(action='DESELECT')
obj.select = True
scene.objects.active = obj
print("current",obj.name,"selected",context.selected_objects[0].name,"active",scene.objects.active.name)
bpy.ops.object.shade_smooth()
bpy.ops.object.modifier_add(type='TRIANGULATE')
return {"FINISHED"}
class LayoutDemoPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "Layout Demo"
bl_idname = "SCENE_PT_layout"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "object"
def draw(self, context):
self.layout.operator("object.simple_operator")
def register():
bpy.utils.register_class(SimpleOperator)
bpy.utils.register_class(LayoutDemoPanel)
def unregister():
bpy.utils.unregister_class(SimpleOperator)
bpy.utils.unregister_class(LayoutDemoPanel)
if __name__ == "__main__":
register()
bpy.ops.object.shade_smooth()
works while bpy.ops.object.modifier_add()
doesn’t do anything. I recently figured that the ‘scene’ context works almost as the context (/hidden state) the bpy.ops.text.run_script()
uses, but it’s not exactly the same:
From here: /t/script-crashes-blender-is-there-a-way-to-somehow-bypass-the-hidden-states-set-by-ui-widgets/1117157:
import bpy
def selectAndActivate(obj, select_children = False):
bpy.ops.object.select_all(action='DESELECT')
obj.select = True
bpy.context.scene.objects.active = obj
if select_children:
bpy.ops.object.select_grouped(extend=True, type='CHILDREN_RECURSIVE')
def TestObj():
selectAndActivate(bpy.context.selected_objects[0])
bpy.ops.mesh.customdata_custom_splitnormals_clear()
class TestItOp(bpy.types.Operator):
bl_idname = "object.test_selection"
bl_label = "Test Selection"
@classmethod
def poll(cls, context):
return True
def execute(self, context):
TestObj()
return {'FINISHED'}
class TestPanel(bpy.types.Panel):
bl_label = "Test It!"
bl_idname = "TEST_it_panel"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
def draw(self, context):
layout = self.layout
layout.row().operator("object.test_selection")
if __name__ == "__main__":
bpy.utils.register_class(TestItOp)
bpy.utils.register_class(TestPanel)
(Needs to select something e.g. default cube)
Blender simply crashes and there’s no debug info other than an access exception error.
Please note that both scripts run fine in a plain python file, but it’s not convenient to switch scripts in the text editor, so I just want to add some UI buttons for them, but no matter what I do that changes some hidden state so the scripts either stop working or simply crash Blender. I’m a total noob but those scripts seem legit to me. What am I doing wrong?
I am using the other API and it works fine, for example custom object properties and such. I’m only having problem running the logic.
I’m using latest 2.79 on Windows 7 (both 64-bit).
Thank you in advance.
PS: This forum says errors with the message: new users can have 2 links in a post when I try to submit this, but I have only 2 links