18
$\begingroup$

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.

$\endgroup$
0

1 Answer 1

34
$\begingroup$

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)
$\endgroup$
4
  • 1
    $\begingroup$ this does not copy the rigidbody $\endgroup$ Commented May 8, 2018 at 21:26
  • 2
    $\begingroup$ @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. $\endgroup$
    – sambler
    Commented May 9, 2018 at 5:48
  • 1
    $\begingroup$ 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? $\endgroup$
    – Will Chen
    Commented Mar 21, 2021 at 14:01
  • $\begingroup$ 'set' object has no attribute 'data' at "new_obj.data = src_obj.data.copy()" $\endgroup$
    – Phil
    Commented Apr 25, 2022 at 20:51

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