5
$\begingroup$

I want to add a lamp the current scene using python on startup. I do not want to change the default scene.

Here is the code that I am using:

import bpy

bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

It adds a point lamp at origin. Like this answer suggests: I have saved this file in scripts/startup as a add_lamp.py

How ever when I start blender nothing has changed. I see no lamps added.

$\endgroup$
8
$\begingroup$

Background Info...

Blender intentionally prevents you from manipulating the scene at startup, this is because it is rarely useful and you end up running into issues - like loading a blend file immediately overwrite any changes you have made.

Other data such as the user preferences can be manipulated since this persists across different blend files.

1. Explicit Execution

So, if you want to do this, you can use a command line argument to run a text block in your startup.blend:

blender --python-text lamp.py

Or you can reference a path directly:

blender --python /path/to/lamp.py

This way you can control if the script runs before or after loading a blend file.

# add the lamp to any blend you open
blender example.blend --python-text lamp.py

# add the lamp, then overwrite it (not useful in this case)
blender --python-text lamp.py example.blend

The main drawback for this is it needs to be added to some startup script or launcher, or manually entered into the commandline each time you start blender.


2. Using Callbacks

Heres an example of a script you can place in startup/ which adds a handler that can manipulate the scene how you like.

import bpy

def load_handler(dummy):
    bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

bpy.app.handlers.load_post.append(load_handler)

This is another example which keeps the handler active but only executes on new files.

import bpy
from bpy.app.handlers import persistent

@persistent
def load_handler(dummy):

    # only apply to startup
    if not bpy.data.filepath:
        return

    bpy.ops.object.lamp_add(type='POINT', view_align=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0), layers=(True, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))

bpy.app.handlers.load_post.append(load_handler)

This may seem overkill for such a simple task, but when you consider it gives you the ability to execute code on any newly loaded file, its quite flexible.

$\endgroup$
  • $\begingroup$ I want to achieve this with both pieces of code in method 2. I also tried using blender --python-text lamp.py. But it did not work. $\endgroup$ – Vader Mar 2 '14 at 14:41
  • $\begingroup$ --python-text relies on the textblock being available in bpy.data.texts, it should work as long as the text's available. $\endgroup$ – ideasman42 Mar 2 '14 at 15:04
  • $\begingroup$ Why did neither method for the callacks work? $\endgroup$ – Vader Mar 2 '14 at 15:07
  • $\begingroup$ You ask why something failed without providing any info, Im not even sure what neither method for the callacks means. If something fails you need to provide a way to redo the failure, it could even be a bug, though in this case I doubt it since the features have been used/tested fairly well. $\endgroup$ – ideasman42 Mar 3 '14 at 6:53
2
$\begingroup$

You're probably using 2.7, the console now prints:

Warning! 'C:\Users\user\blender-2.70-testbuild1-win64\2.69\scripts\startup\lamps.py' 
has no register function, this is now a requirement for registerable scripts

You would need to add a register function to you script.

I tried this:

import bpy

def register():
    print("add")

this works, but your operator invocation leads to:

Traceback (most recent call last):
  File "C:\Users\user\blender-2.70-testbuild1-win64\2.69\scripts\modules\bpy\utils.py", line 160, in register_module_call
    register()
  File "C:\Users\user\blender-2.70-testbuild1-win64\2.69\scripts\startup\lamps.py", line 5, in register
    bpy.ops.objects.lamp_add(type='POINT', view_align=False, location=(0.0, 0.0, 0.0), rotation=(0.0, 0.0, 0.0),layers=(True, False,
 False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False, False))
  File "C:\Users\user\blender-2.70-testbuild1-win64\2.69\scripts\modules\bpy\ops.py", line 182, in __call__
    BPyOpsSubModOp._scene_update(context)
  File "C:\Users\user\blender-2.70-testbuild1-win64\2.69\scripts\modules\bpy\ops.py", line 148, in _scene_update
    scene = context.scene
AttributeError: '_RestrictContext' object has no attribute 'scene'
$\endgroup$
  • $\begingroup$ I opened the python file in the text editor and checked the register box. And still nothing $\endgroup$ – Vader Mar 1 '14 at 22:00
  • $\begingroup$ this script works when I run it from the text editor, why does it not work as a start up script? $\endgroup$ – Vader Mar 1 '14 at 22:32
  • $\begingroup$ @Vader I'm sorry this doesn't answer your question. Should I delete it or keep it for further reference? $\endgroup$ – stacker Mar 1 '14 at 22:33
  • $\begingroup$ keep it. We can always fix this. Maybe some devs will be able to explain this $\endgroup$ – Vader Mar 1 '14 at 22:33
  • $\begingroup$ Perhaps the operators are not available in this state of initialization. $\endgroup$ – stacker Mar 1 '14 at 22:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.