17

I would like to duplicate a mesh object, but on a particular object. Right now this is working:

import bpy 

for i in range (0,5):
    bpy.ops.object.duplicate(linked=0,mode='TRANSLATION') 
    bpy.data.objects['cube.001'].animation_data_clear()

The way I want it to do it though is that the script should only duplicate a particular object in the scene that I enter through as a string name. ATM its just duplicating the 1st object and duplicating the duplicates of the duplicates.

p2or
  • 15,860
  • 10
  • 83
  • 143
Raspberry
  • 425
  • 1
  • 5
  • 11

1 Answers1

33

The operator bpy.ops.object.duplicate() will duplicate the selected objects and then make the new duplicate objects selected while de-selecting the original objects. The operator is designed for user interaction which actually leaves the user moving the new duplicates when it is done (when started through the gui).

A better way to create a copy of an object by script is to use the copy() method available to most datablocks and then link it to a collection using CollectionObjects.link() in Blender 2.8x or to the scene using scene.objects.link() in Blender 2.7x. Note that the new object will use the same mesh datablock as the original, you can duplicate that as well while you are creating copies, you may also want to consider other data such as particle systems and materials. Instead of starting with the active object you can also specify an exact object with src_obj = bpy.data.objects['Cube']

Blender 2.8x

import bpy

C = bpy.context src_obj = bpy.context.active_object

for i in range (0,5): new_obj = src_obj.copy() new_obj.data = src_obj.data.copy() new_obj.animation_data_clear() C.collection.objects.link(new_obj)

Blender 2.7x

import bpy

scn = bpy.context.scene src_obj = bpy.context.active_object

for i in range (0,5): new_obj = src_obj.copy() new_obj.data = src_obj.data.copy() new_obj.animation_data_clear() scn.objects.link(new_obj)

brockmann
  • 12,613
  • 4
  • 50
  • 93
sambler
  • 55,387
  • 3
  • 59
  • 192
  • 1
    this does not copy the rigidbody – sliders_alpha May 08 '18 at 21:26
  • 2
    @sliders_alpha Actually the rigid body setting do get copied, but the new object doesn't get added to the rigid body group. Try adding bpy.data.groups['RigidBodyWorld'].objects.link(new_obj) inside the loop. – sambler May 09 '18 at 05:48
  • 1
    The .ops calls will also preserve relative relationship links— including in modifiers, constraints, and drivers, I believe— between the copied objects. What would be the most efficient way to replicate that behaviour with "low-level" calls? – Will Chen Mar 21 '21 at 14:01
  • 'set' object has no attribute 'data' at "new_obj.data = src_obj.data.copy()" – Phil Apr 25 '22 at 20:51