1
$\begingroup$

Dears, I am trying to create a simple empty room using Python scripts. But when I tried to reach the object using "bpy.context.object" to scale it, the compiler stops and give me this error. "AttributeError: 'Context' object has no attribute 'object'". I looked in the documentation and it exists.

Can you please tell me what is wrong with my code? I am using Blender v3.6.5.

Many thanks in advance.

import bpy

# Clear existing mesh objects
bpy.ops.wm.read_factory_settings(use_empty=True)

# Set units to metric
bpy.context.scene.unit_settings.system = 'METRIC'
bpy.context.scene.unit_settings.scale_length = 1.0

# Create a wooden floor
bpy.ops.mesh.primitive_plane_add(size=8, align='WORLD', location=(0, 0, 0))
floor = bpy.context.object
floor.scale[0] = 2  # Scale it to 16x16 meters
floor.scale[1] = 2
floor.name = 'Wooden Floor'

# Create white walls
wall_thickness = 0.1  # Thickness of the walls
wall_height = 4.0  # Height of the walls

# Create walls
walls_data = [
    (8, -1, 0, wall_thickness, 18, wall_height),  # Left wall
    (8, 17, 0, wall_thickness, 18, wall_height),  # Right wall
    (-1, 8, 0, 18, wall_thickness, wall_height),  # Back wall
    (17, 8, 0, 18, wall_thickness, wall_height),  # Front wall
]

walls = []

for i, (x, y, z, sx, sy, sz) in enumerate(walls_data):
    bpy.ops.mesh.primitive_cube_add(size=1, location=(x, y, z + sz / 2))
    wall = bpy.context.object
    wall.scale[0] = sx
    wall.scale[1] = sy
    wall.scale[2] = sz
    wall.name = f'Wall {i + 1}'
    walls.append(wall)

# Set materials for the floor
floor.data.materials.append(bpy.data.materials.new(name='Wooden Floor Material'))
floor.active_material.diffuse_color = (0.5, 0.3, 0.1, 1)  # Brown color for wood

# Set materials for the walls
for wall in walls:
    wall.data.materials.append(bpy.data.materials.new(name='White Wall Material'))
    wall.active_material.diffuse_color = (1, 1, 1, 1)  # White color for walls
$\endgroup$

1 Answer 1

1
$\begingroup$

You need to add a timer, when you reload a file there is at least one tick where the context is not initialized.

BTW I suspect this is an artifact of using a LLM like ChatGPT to produce the code, but being overzealous with comments can be detrimental to the script. I advise you to rather use descriptive function names. Also resetting factory settings is a weird choice, I think you want to load a new file.

import bpy

def set_units_to_metric():
    bpy.context.scene.unit_settings.system = 'METRIC'
    bpy.context.scene.unit_settings.scale_length = 1.0

def create_wooden_floor():
    bpy.ops.mesh.primitive_plane_add(size=8, align='WORLD', location=(0, 0, 0))
    floor = bpy.context.object
    floor.scale[0] = 2  # Scale it to 16x16 meters
    floor.scale[1] = 2
    floor.name = 'Wooden Floor'
    return floor

def create_walls():
    wall_thickness = 0.1  # Thickness of the walls
    wall_height = 4.0  # Height of the walls

    walls_data = [
        (8, -1, 0, wall_thickness, 18, wall_height),  # Left wall
        (8, 17, 0, wall_thickness, 18, wall_height),  # Right wall
        (-1, 8, 0, 18, wall_thickness, wall_height),  # Back wall
        (17, 8, 0, 18, wall_thickness, wall_height),  # Front wall
    ]

    walls = []

    for i, (x, y, z, sx, sy, sz) in enumerate(walls_data):
        bpy.ops.mesh.primitive_cube_add(size=1, location=(x, y, z + sz / 2))
        wall = bpy.context.object
        wall.scale[0] = sx
        wall.scale[1] = sy
        wall.scale[2] = sz
        wall.name = f'Wall {i + 1}'
        walls.append(wall)
    return walls

def set_floor_materials(floor):
    floor.data.materials.append(bpy.data.materials.new(name='Wooden Floor Material'))
    floor.active_material.diffuse_color = (0.5, 0.3, 0.1, 1)  # Brown color for wood
    
def set_walls_materials(walls):
    for wall in walls:
        wall.data.materials.append(bpy.data.materials.new(name='White Wall Material'))
        wall.active_material.diffuse_color = (1, 1, 1, 1)  # White color for walls

def main():
    set_units_to_metric()
    floor = create_wooden_floor()
    walls = create_walls()
    set_floor_materials(floor)
    set_walls_materials(walls)

if __name__ == "__main__":
    bpy.ops.wm.read_homefile()
    bpy.app.timers.register(main, first_interval=0.01)
$\endgroup$

You must log in to answer this question.

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