I was making a Blender add-on that can create a predefined light-setup and generate HDRIs. For this it changes some settings of the camera in the scene.
The script creates two sections named Illumin8r Quick Lights and Illumin8r HDRI Maker in the Scene Properties tab with each two buttons. The HDRI buttons require the camera to be selected in order to change its settings.
I run into this error when I click the buttons Turn scene into HDIR and Turn settings back to normal in the Illumin8r HDRI Maker section (LayoutDemoPanel2 class in the script):
Error:
File "C:\Users\....\w3.blend\Text", line 147, in execute
File "C:\Users\....\w3.blend\Text", line 131, in button3
AttributeError: 'NoneType' object has no attribute 'data
The error seems to be related with the following lines
def button3(context):
// ...
bpy.context.object.data.type = 'PANO'
bpy.context.object.data.cycles.panorama_type = 'EQUIRECTANGULAR'
and
def button4(context):
bpy.context.object.data.type = 'PERSP'
bpy.context.object.data.cycles.panorama_type = 'FISHEYE_EQUISOLID'
The script looks like this:
bl_info = {
"name": "Illumin8r",
"author": "BinaryOdysseus",
}
import bpy
target_obj = bpy.context.scene.objects[0]
collection = bpy.context.collection
def create_point_light1(name):
light_data = bpy.data.lights.new(name=name, type='POINT')
light_data.color = (1,1,1)
light_data.energy = 100
light_data.shadow_soft_size = 1.75
light_object = bpy.data.objects.new(name=name, object_data=light_data)
light_object.location = (1.35, -2.5, 2.56)
bpy.context.collection.objects.link(light_object)
def create_point_light2(name):
light_data = bpy.data.lights.new(name=name, type='POINT')
light_data.color = (1,1,1)
light_data.energy = 250
light_data.shadow_soft_size = 1.75
light_object = bpy.data.objects.new(name=name, object_data=light_data)
light_object.location = (-1.175, -5.5, 4.64)
bpy.context.collection.objects.link(light_object)
def create_point_light3(name):
light_data = bpy.data.lights.new(name=name, type='POINT')
light_data.color = (1,1,1)
light_data.energy = 500
light_data.shadow_soft_size = 2.15
light_object = bpy.data.objects.new(name=name, object_data=light_data)
light_object.location = (-6.7, -0.1, 2.2)
bpy.context.collection.objects.link(light_object)
def create_point_light4(name):
light_data = bpy.data.lights.new(name=name, type='POINT')
light_data.color = (1, 0.612277, 0.441099)
light_data.energy = 1000
light_data.shadow_soft_size = 3.17
light_object = bpy.data.objects.new(name=name, object_data=light_data)
light_object.location = (0, -0.6, 3.2)
bpy.context.collection.objects.link(light_object)
def create_spot_light(name):
light_data = bpy.data.lights.new(name=name, type='SPOT')
light_data.color = (1, 0.868938, 0.686679)
light_data.energy = 10000
light_data.spot_size = 180
light_object = bpy.data.objects.new(name=name, object_data=light_data)
light_object.location = (0, 0, 14)
bpy.context.collection.objects.link(light_object)
def create_sun_light(name):
light_data = bpy.data.lights.new(name=name, type='SUN')
light_data.color = (1, 0.984, 0.675)
light_object = bpy.data.objects.new(name=name, object_data=light_data)
light_object.location = (0, 0, 14)
light_constraint = light_object.constraints.new(type='TRACK_TO')
light_constraint.target = target_obj
light_constraint.track_axis = 'TRACK_NEGATIVE_Z'
light_constraint.up_axis = 'UP_Y'
bpy.context.collection.objects.link(light_object)
def button1(context):
create_point_light1("Point")
create_point_light2("Point")
create_point_light3("Point")
create_point_light4("Point")
create_spot_light("Spot")
create_sun_light("Sun")
class Add_Lights(bpy.types.Operator):
"""Tooltip"""
bl_idname = "illumin8r.add_lights"
bl_label = "Add quick lights"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
button1(context)
return {'FINISHED'}
def button2(context):
bpy.ops.object.select_by_type(type = 'LIGHT')
bpy.ops.object.delete(use_global=False, confirm=False)
class Remove_Lights(bpy.types.Operator):
"""Tooltip"""
bl_idname = "illumin8r.remove_lights"
bl_label = "Remove all lights"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
button2(context)
return {'FINISHED'}
def button3(context):
bpy.context.scene.render.engine = 'CYCLES'
bpy.context.object.data.type = 'PANO'
bpy.context.object.data.cycles.panorama_type = 'EQUIRECTANGULAR'
bpy.context.scene.render.resolution_percentage = 200
bpy.context.scene.render.image_settings.file_format = 'HDR'
class Make_Scene_HDRI(bpy.types.Operator):
"""Tooltip"""
bl_idname = "illumin8r.make_scene_hrdi"
bl_label = "Turn scene into HDRI"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
button3(context)
return {'FINISHED'}
def button4(context):
bpy.context.object.data.type = 'PERSP'
bpy.context.object.data.cycles.panorama_type = 'FISHEYE_EQUISOLID'
bpy.context.scene.render.resolution_percentage = 100
bpy.context.scene.render.image_settings.file_format = 'PNG'
class Make_Scene_Normal(bpy.types.Operator):
"""Tooltip"""
bl_idname = "illumin8r.make_scene_normal"
bl_label = "Turn settings back to normal"
@classmethod
def poll(cls, context):
return context.active_object is not None
def execute(self, context):
button4(context)
return {'FINISHED'}
def menu_func(self, context):
self.layout.operator(SimpleOperator.bl_idname, text=SimpleOperator.bl_label)
class LayoutDemoPanel(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "Illumin8r Quick Lights"
bl_idname = "SCENE_PT_layout"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
def draw(self, context):
layout = self.layout
scene = context.scene
# Big buttons
row = layout.row()
row.scale_y = 1.25
row.operator("illumin8r.add_lights")
row = layout.row()
row.scale_y = 1.25
row.operator("illumin8r.remove_lights")
class LayoutDemoPanel2(bpy.types.Panel):
"""Creates a Panel in the scene context of the properties editor"""
bl_label = "Illumin8r HDRI Maker"
bl_idname = "SCENE_PT_layout_2"
bl_space_type = 'PROPERTIES'
bl_region_type = 'WINDOW'
bl_context = "scene"
def draw(self, context):
layout = self.layout
scene = context.scene
# Big buttons
row = layout.row()
row.scale_y = 1.25
row.operator("illumin8r.make_scene_hrdi")
row = layout.row()
row.scale_y = 1.25
row.operator("illumin8r.make_scene_normal")
def register():
bpy.utils.register_class(Make_Scene_HDRI)
bpy.utils.register_class(Make_Scene_Normal)
bpy.utils.register_class(Remove_Lights)
bpy.utils.register_class(Add_Lights)
bpy.types.VIEW3D_MT_object.append(menu_func)
bpy.utils.register_class(LayoutDemoPanel)
bpy.utils.register_class(LayoutDemoPanel2)
def unregister():
bpy.utils.unregister_class(Make_Scene_HDRI)
bpy.utils.unregister_class(Make_Scene_Normal)
bpy.utils.unregister_class(Remove_Lights)
bpy.utils.unregister_class(Add_Lights)
bpy.types.VIEW3D_MT_object.remove(menu_func)
bpy.utils.unregister_class(LayoutDemoPanel)
bpy.utils.unregister_class(LayoutDemoPanel2)
if __name__ == "__main__":
register()