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
collection.objects.link(ob)
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.animation_data.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]},
linked=True)
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)
collection.objects.link(new_object)
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