-1
$\begingroup$

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()
$\endgroup$
2
  • $\begingroup$ Hi and welcome! You need to add more details to your question. 1) where are the buttons that cause the error? (A: Scene Properties tab > Illumin8r HDRI Maker) 2) what's the name of the button? (A: button Turn scene into HDRI) 3) Must an object be selected? Also, the error occurs in line 131 not 147: bpy.context.object.data.type = 'PANO'. The object is the active object. 4) What kind of object should that be? Mesh objects like the default cube have not data.type. This is what the error tells you. 5) What means 'PANO'? 6) What are you trying to do here? $\endgroup$
    – Blunder
    Commented Mar 5, 2023 at 2:22
  • $\begingroup$ Ok, you have to select the Camera object to make your script work. $\endgroup$
    – Blunder
    Commented Mar 5, 2023 at 3:08

1 Answer 1

0
$\begingroup$

The problem is the following function that is executed when the button "Turn scene into HDRI" is pressed:

    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'

  1. you use bpy.context and not the given context object
  2. the error happens because in your case (or better context) context.active_object is the camera and context.object is None. They are not the same. See the question "https://blender.stackexchange.com/q/204074/107598" for another side case.

Fixed version:

    def button3(context):
        context.scene.render.engine = 'CYCLES'
        context.active_object.data.type = 'PANO'
        context.active_object.data.cycles.panorama_type = 'EQUIRECTANGULAR'
        context.scene.render.resolution_percentage = 200
        context.scene.render.image_settings.file_format = 'HDR'

Do the same for def button4(context):.

you could also create a new object like this:

def button3(context):

bpy.context.scene.render.resolution_percentage = 200
bpy.context.scene.render.image_settings.file_format = 'HDR'

camera_data = bpy.data.cameras.new(name="hi")


camera_object = bpy.data.objects.new(name="HDRI Camera", object_data=camera_data)
camera_object.location = (0, 0, 4)
camera_object.data.type = 'PANO'
camera_object.data.cycles.panorama_type = 'EQUIRECTANGULAR'



bpy.context.collection.objects.link(camera_object)
$\endgroup$

You must log in to answer this question.

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