3

How can I create an empty / null / locator object using python? I'd like to create one for each selected object and then all empties should be parented or constraint to the selected objects, meaning that the rotation and position should be copied over as well.

I tried something along these lines but I can't get it to work properly:

import bpy

for obj in bpy.context.selected_objects: bpy.ops.object.empty_add()

Q: How to create an empty per object in selection?

brockmann
  • 12,613
  • 4
  • 50
  • 93
  • 1
    Pull down the hidden window at the top of Blender and watch the Python it writes as you do the actions. Update your question with how far you get. – rob Mar 21 '19 at 08:56
  • Related: https://blender.stackexchange.com/questions/202509/assigning-an-empty-parent-object/202546#202546 – brockmann Nov 25 '20 at 09:32

2 Answers2

4

Update for 2.8 +

import bpy

for obj in bpy.context.selected_objects: # Loop over all selected objects empty = bpy.data.objects.new(obj.name + "_Empty", None) # Create new empty object obj.users_collection[0].objects.link(empty) # Link empty to the current object's collection empty.empty_display_type = 'PLAIN_AXES' empty.parent = obj

If you want the empties to be the parents :

import bpy

for obj in bpy.context.selected_objects: # Loop over all selected objects empty = bpy.data.objects.new(obj.name + "_Empty", None) # Create new empty object obj.users_collection[0].objects.link(empty) # Link empty to the current object's collection empty.empty_display_type = 'PLAIN_AXES' empty.location = obj.location obj.parent = empty obj.location = (0, 0, 0)

Gorgious
  • 30,723
  • 2
  • 44
  • 101
2

bpy.ops.object.empty_add()

You can call bpy.ops.object.empty_add() operator per object and pass the location, rotation and scale for each object as well:

Blender 2.8+

import bpy

for obj in bpy.context.selected_objects: # Create the empty using the operator bpy.ops.object.empty_add(type='PLAIN_AXES', location=obj.location) # Get the newly created empty empty = bpy.context.view_layer.objects.active # Set the size empty.empty_display_size = 20 # Parent the object to the empty obj.parent = empty

Blender 2.7x

import bpy

selected_objs = bpy.context.selected_objects for obj in selected_objs: # Create the empty using the operator bpy.ops.object.empty_add(type='PLAIN_AXES', location=obj.location) # Get the newly created empty empty = bpy.context.scene.objects.active # Parent the object to the empty obj.parent = empty

I think it's quite straightforward, tell me if you have problems

brockmann
  • 12,613
  • 4
  • 50
  • 93
Tareyes
  • 1,794
  • 6
  • 18
  • What if you want all the bones on the armature? – NoobProgrammerxPython Mar 24 '19 at 11:20
  • 1
    that's a different question, you should have stated it more clearly... Currently I'm not home, so i can't verify, but create the empty with the method i told you (except that you need to put the bone's position instead of the obj.position), then to parent them, add a constraint modifier on the empty and the set the bone as target – Tareyes Mar 25 '19 at 10:59
  • I am excited to use this, especially because empties allow you to place a collection instance on them. However, this python script is broken in 2.82a. Trying to go through the errors and update the script for compatibility. – Coby Randal Mar 16 '20 at 21:42
  • @CobyRandal yes, this code was made for version 2.79, and from 2.79 to 2.80 the API was modified. In newer version the commands are a bit different, but the logic is still the same – Tareyes Mar 17 '20 at 23:25
  • So I have a working script that places an empty (with a collection instance) at all objects you select. It takes into account the selected objects and their rotations. I never got the parenting to work right though, which is why I have refrained from answering this question as of yet. Any ideas how to make parenting work like this in 2.8? The farthest I got was it made all instances children of the first object selected instead of each object at which they are placed like I originally wanted. – Coby Randal Apr 08 '20 at 21:16
  • 1
    @CobyRandal See my answer for updated code. Add empty.instance_type = 'COLLECTION' and empty.instance_collection = bpy.data.collections.get('MyCollection') at the end of the loop to create a collection instancer – Gorgious Apr 24 '20 at 07:43