1

I found such a script in this post Is there any way to use input() or raw_input() functions in blender scripting?

import bpy
import mathutils as math

This class is the actual dialog that pops up to create the cube

class AddCubeDialogOperator(bpy.types.Operator): bl_idname = "object.add_cube_dialog" bl_label = "Add Cube"

# Here you declare everything you want to show in the dialog 
name = bpy.props.StringProperty(name = "Objects Name:", default = "Cube")
scale = bpy.props.FloatVectorProperty(name = "Scale:", default = (1.0, 1.0, 1.0)) 

# This is the method that is called when the ok button is pressed
# which is what calls the AddCube() method 
def execute(self, context):        
    AddCube(self.name, self.scale)
    self.report({'INFO'}, "Added Cube")
    return {'FINISHED'}

# This is called when the operator is called, this "shows" the dialog 
def invoke(self, context, event):
    wm = context.window_manager
    return wm.invoke_props_dialog(self)

This method adds a cube to the current scene and then applys scale and

name to the cube

def AddCube(name, scale): bpy.ops.mesh.primitive_cube_add() bpy.context.scene.objects.active.name = name bpy.context.scene.objects.active.scale = scale

Registers the cube dialog to blender so that it can be called

bpy.utils.register_class(AddCubeDialogOperator)

Calls the menu when the script is ran

bpy.ops.object.add_cube_dialog('INVOKE_DEFAULT')

This scrpt was written for Blender 2.79. I think so. Under Blender 2.8x is running, there is a dialog box, there is possibility to choose scale, but When I press OK, I have such errors:

line 16, in execute

AddCube(self.name, self.scale)

line 29, in AddCube AttributeError: 'bpy_prop_collection' object has no attribute 'active'

AddCube AttributeError: 'bpy_prop_collection' object has no attribute 'active' Line 29 is:

bpy.context.scene.objects.active.name = name

What needs to be changed to make this scrypt work properly under Blender 2.8x

Neuroup
  • 31
  • 1
  • 1
  • 7

2 Answers2

2

Scene.objects.active is no longer valid

For 2.8 to get or set the active object use

context.view_layer.objects.active = ob

however after an operator call the object has context, so with minimal changes

    def execute(self, context):        
        add_cube(context, self.name, self.scale)
        self.report({'INFO'}, "Added Cube")
        return {'FINISHED'}
# This is called when the operator is called, this "shows" the dialog 
def invoke(self, context, event):
    wm = context.window_manager
    return wm.invoke_props_dialog(self)

This method adds a cube to the current scene and then applys scale and

name to the cube

def add_cube(context, name, scale): bpy.ops.mesh.primitive_cube_add() cube = context.object cube.name = name cube.scale = scale

batFINGER
  • 84,216
  • 10
  • 108
  • 233
1

When using a context in an operator you should use the context provided in the execute method, or else you risk encountering invalid context error.

Although this is not why you get an error in this case. Here you can simply use context.active_object since this will default to the newly created cube.

Replace your execute method with :

def execute(self, context):        
    AddCube(context, self.name, self.scale)
    self.report({'INFO'}, "Added Cube")
    return {'FINISHED'}

And your AddCube method with :

def AddCube(context, name, scale):
    bpy.ops.mesh.primitive_cube_add() 
    context.active_object.name = name
    context.active_object.scale = scale
Gorgious
  • 30,723
  • 2
  • 44
  • 101