# How to duplicate an object in 2.8 via the Python API, without using bpy.ops.object.add_named()

I know how to successfully duplicate an object by using

bpy.ops.object.add_named(name = 'TemplateObjectName')


If the template object named 'TemplateObjectName' has animations, particle systems and modifiers attached to it, the previous call will create a duplicate object that also has those components. However, if I duplicate an object using

template_object = bpy.data.objects['TemplateObjectName']
new_object = bpy.data.objects.new('NewObjectName', template_object.data)


how do I attach the template object's animation, modifiers, particle systems...?

Make copies of ID data with ID.copy()

For blender data ID objects ie objects in bpy.data.objects meshes in bpy.data.meshes actions in bpy.data.actions the ID object has a copy method .

For a bpy.types.Object object copy, the copy will have the same transforms, parent, modifiers, constraints, animation data et all of the original. All linked data will be same as original. eg if mesh of original is bpy.data.meshes["Cube"] so is the copy's. Fortunately the mesh also has a copy method.

template_ob = bpy.data.objects.get("template")
if template_ob:
ob = template_ob.copy()
# link to collection if need be


the copy ob has the same linked data as the original template_ob.data is ob.data is True.

    # assign a copy of the mesh to copy object
ob.data = ob.data.copy()


Assuming we've checked original has an action then to make the action a copy of original's

    action = ob.animation_data.action
# make it a copy
ob.animation_data.action = action.copy()


To unassign

    #make it None (no action assigned)
ob.action = None


Or in one fell swoop, remove all animation data including actions and drivers

    ob.animation_data_clear()


Constraints and modifiers data are not linked. The copy has the same of each, including the same names, as original. The vertex groups and target objects pointed to will be same as original, and may need to be adjusted.

To remove all modifiers and constraints on copy

    ob.modifiers.clear()
ob.constraints.clear()


Duplicate Object operator. bpy.ops.object.duplicate()

can also use the duplicate operator. As with operators they work on the context and selected objects, which if need be can be set within a script.

Alternatively with an override dictionary. Early testing and 2.8 appears much simpler on this front.

Test code (can confirm works as expected when run in python console on 2.8)

Duplicate an object template_ob with linked data

bpy.ops.object.duplicate(
{"object" : template_ob,
"selected_objects" : [template_ob]},
ob = context.object # newly duped object


linked=False is the default.

Making a new object with copies of originals data.

From question:

template_object = bpy.data.objects['TemplateObjectName']
new_object = bpy.data.objects.new('NewObjectName', template_object.data)


how do I attach the template object's animation, modifiers, particle systems...?

Strictly speaking this is not a duplicate. It is a new object that shares the originals data part. Or similarly in your answer where it shares data part, and original action or copy thereof. Results will match in the simplest of cases, ..and may be the answer you are seeking. However for others wishing to duplicate their objects in 2.8 using this method

Can they be assured that nothing is affected by not having a property of original on the new object?

• The action or driver may refer to data paths of properties on original that either, will not be defined, or set to default on the new object.
• Relations: modifiers constraints animations could require the original having a certain parent or transform.
• How to go about copying over the constraints / modifiers of the original? What if they have drivers? Should target objects be duped,
• Vertex groups? .

To reiterate, making a new object sharing some chosen DNA of the original is IMO not duplicating. Obviously there's no need to write a script with all the options required to emulate ob.copy() just like there's no need to use ob.copy() to add a new object with default settings, and only a few chosen attributes of ob

Putting the body of Porsche on your new car, and driving it like it's a Porsche, doesn't make it a Porsche, it may however achieve the result you are after

• Thanks @batFINGER for your answers. They didn't just solve my problem, they also provided much needed general knowledge that I much in need of. – Dazotaro Apr 2 '19 at 16:20
• Thanks @p2or for your answers. They didn't just solve my problem, they also provided much needed general knowledge that I much in need of. – Dazotaro Apr 2 '19 at 16:20

This is how you can duplicate the object: linking the original object's mesh data, and with/without linking the original object's animation data:

template_object = bpy.data.objects.get('TemplateObjectName')
if template_object:
# Create the new object by linking to the template's mesh data
new_object = bpy.data.objects.new('NewObjectName', template_object.data)
# Create a new animation for the newly created object
animation = new_object.animation_data_create()

#-------------------------
#Assign the template object's action to the new animation
animation.action = template_object.animation_data.action